2012-04-16 29 views
12

Nếu mỗi luồng được đảm bảo chỉ đọc/ghi vào một tập hợp con cụ thể của mảng, có thể nhiều chuỗi hoạt động trên cùng một mảng (tĩnh) mà không cần đến các phần quan trọng, v.v ... không?Có thể truy cập các mảng tĩnh một cách an toàn từ nhiều luồng không?

CHỈNH SỬA - Điều này dành cho trường hợp cụ thể của mảng các loại không được tính tham chiếu và ghi/đóng gói hồ sơ của chúng.

Nếu có, hãy cẩn thận?

Cảm giác ruột của tôi là có nhưng ruột của tôi đôi khi có thể là một nguồn thông tin không đáng tin cậy.

+0

OK, tôi biết điều đó có nghĩa là gì bây giờ. Tôi gọi đó là kích thước cố định nhưng bạn sẽ đi. Nó làm cho không có sự khác biệt hay không kích thước là cố định. Nó không tạo ra sự khác biệt cho dù mảng có thuộc phạm vi toàn cầu, cục bộ hay lớp hay không. Nó làm cho không có sự khác biệt hay không mảng được phân bổ heap hoặc ngăn xếp được phân bổ. Nó chỉ là một mảng liền kề của các mục. –

+0

Không, sai lầm của tôi. Tôi chưa bao giờ biết được cách sử dụng đó. Tôi đoán nó phải đã được giới thiệu sau khi tôi đã học Delphi tại thời điểm đó mảng năng động đã được thêm vào, vì tất cả các mảng trước khi đó là tĩnh. Trong mọi trường hợp, tĩnh hoặc không làm cho không có sự khác biệt nào cả. –

+0

Đủ công bằng. Như bạn nói, trong mọi trường hợp, có vẻ như không phải là một lý do rõ ràng tại sao truy cập đồng thời nên là một vấn đề, nhưng đôi khi có những sự tinh tế tối mà làm xáo trộn những thứ như vậy. Đôi khi nó là tốt đẹp để được gấp đôi nhất định. –

Trả lời

8

Giả sử rằng:

  1. Bạn có một trường hợp duy nhất của một mảng (tĩnh hoặc động), và
  2. Các yếu tố của mảng là kiểu giá trị thuần túy (tức là không chứa tài liệu tham khảo), và
  3. Mỗi luồng hoạt động trên các mảng phụ tách rời và
  4. Không có gì khác trong hệ thống ghi vào mảng trong khi các luồng đang hoạt động trên đó.

Với những điều kiện này, tôi tin rằng cấu trúc dữ liệu và mẫu luồng của bạn đáp ứng, thì tất cả các thuật toán đều an toàn chỉ.

+0

Tôi cho rằng điều này cũng sẽ là trường hợp với các đối tượng kiểu tham chiếu IF tham chiếu đến cùng một đối tượng được đảm bảo chỉ tồn tại trong một mảng phụ (ví dụ: không có tham chiếu chung được chia sẻ giữa các mảng phụ phân tách). –

+2

@J ... Đúng vậy. Vì vậy, miễn là mỗi luồng hoạt động trên dữ liệu riêng tư cho luồng đó, thì các thuật toán là an toàn luồng. –

+0

@DavidHeffeman, Điều kiện số 4 có thực sự cần thiết không? Sự khác biệt của chủ đề chính hoặc quá trình khác bằng văn bản cho mảng để các chủ đề hoạt động trên nó là gì? – Arnold

7

Không, đây không thể là chủ đề an toàn, trong một số trường hợp.

Tôi thấy ít nhất hai lý do.

1. Nó sẽ phụ thuộc vào nội dung của mảng tĩnh.

Nếu bạn sử dụng một số loại tính không tham chiếu (như double, integer, bytes, shortstring), sẽ không có bất kỳ vấn đề nào trong nhiều trường hợp (ít nhất là nếu dữ liệu chỉ đọc/đọc).

Nhưng nếu bạn sử dụng một số loại được tính tham chiếu (như string, interface hoặc mảng động lồng nhau), bạn sẽ phải đảm bảo an toàn luồng.

Đó là:

TMyType1: array[0..1] of integer; // thread-safe on reading 
TMyType2: array[0..1] of string; // may be confusing 

Lưu ý bổ sung: nếu string của bạn là trong thực tế chia sẻ giữa một số tiểu phần của mảng tĩnh, bạn có thể có số lượng tài liệu tham khảo được nhầm lẫn. Trừ khi bạn gọi một cách rõ ràng UniqueString() cho mỗi người (bên trong một phần quan trọng, tôi nghi ngờ). Đối với mảng double hoặc integer, bạn sẽ không gặp phải vấn đề này.

2. Nó sẽ phụ thuộc vào đồng thời truy cập

đọc truy cập nên được chủ đề an toàn, ngay cả đối với tài liệu tham khảo tính loại, nhưng đồng thời ghi có thể gây nhầm lẫn. Đối với một số string, bạn có thể có các vấn đề GPF trong một số trường hợp ngẫu nhiên, đặc biệt là trên một CPU đa lõi.

Một số thực hiện an toàn có thể là:

  • Sử dụng phần quan trọng (nhỏ hơn càng tốt, để giảm chi phí) hoặc các cấu trúc bảo vệ khác;
  • Sử dụng Copy-On-Write hoặc bản sao riêng tư cho mỗi chủ đề của nội dung, để chắc chắn;
  • Lưu ý mới nhất (không phải về an toàn, nhưng hiệu suất): Chia sẻ một mảng giữa nhiều CPU có thể dẫn đến các hình phạt về hiệu suất do đồng bộ hóa bộ nhớ cache giữa các CPU. Hiệu suất đôi khi tốt hơn nhiều khi bạn sử dụng các mảng riêng biệt, đảm bảo cửa sổ bộ đệm L1 của chúng sẽ không được chia sẻ giữa các CPU.

Lưu ý rằng các sự cố như vậy có thể là một cơn ác mộng để gỡ lỗi, phía khách hàng: các vấn đề đồng thời nhiều chủ đề có thể xảy ra ngẫu nhiên và rất khó theo dõi. An toàn hơn, tốt hơn, trừ khi bạn có các vấn đề hiệu suất rõ ràng và đã được chứng minh.

Lưu ý bổ sung: Đối với trường hợp cụ thể của mảng tĩnh đôi, với phần phụ của mảng được truy cập bởi chỉ một chuỗi, nó chỉ an toàn. Nhưng không có quy tắc tuyệt đối nào về độ an toàn của luồng trong mọi tình huống, ngay cả đối với một mảng tĩnh. Ngay sau khi bạn sử dụng một số loại được tính tham chiếu hoặc một số con trỏ, bạn có thể gặp phải các sự cố ngẫu nhiên.

+0

Điểm tốt - Tôi nên có cụ thể về loại mảng. Trong trường hợp này, các phần tử được đóng gói hồ sơ của đôi (mà tôi nghĩ rằng nên được an toàn). –

+0

Câu trả lời này chỉ đơn giản là sai trong quan điểm của tôi. Lực đẩy của câu hỏi là mỗi thread hoạt động trên các mảng phụ rời rạc. Và chỉ có chuỗi sở hữu mỗi mảng con hoạt động trên đó. Đó là chủ đề an toàn cho dù loại phần tử là gì. –

+0

@DavidHeffernan - cũng là một điểm tốt. Mảng các đối tượng được tính tham chiếu chỉ giữ con trỏ, vâng? –

Các vấn đề liên quan