2012-02-16 28 views
6

Tôi đang sử dụng tiêu chuẩn :: vector dưới dạng dữ liệu được chia sẻ trong ứng dụng đa luồng. Tôi đóng gói thread bên trong một lớp học, ví dụ,std :: vector, chủ đề an toàn, đa luồng

class ABC { 
public: 
    double a, b, c; 
}; 

boost::mutex mutex1; 

class XYZ { 
public: 
    XYZ(vector<ABC> & pVector) { 
     ptrVector = &pVector; 
     m_thread = boost::thread(&XYZ::Start, this); 
    } 
    ~XYZ() {} 
    void Start(); 
public: 
    vector<ABC> * ptrVector; 
    boost::thread m_thread; 
};  

void XYZ::Start() { 
    try { 
     while(1) { 
      boost::this_thread::interruption_point(); 
      for (unsigned int i=0; i<ptrVector->size(); i++) { 
       { 
        boost::mutex::scoped_lock lock(mutex1); 
        ptrVector->at(i).a = double(rand())/10000; 
        ptrVector->at(i).b = double(rand())/10000; 
        ptrVector->at(i).c = double(rand())/10000; 
       } 
      } 
     } 
    } 
    catch(boost::thread_interrupted) {} 
    catch(std::exception) {} 
} 

Khi tôi đóng ứng dụng, đôi khi , trong debug, sẽ có 2 thông báo lỗi, đôi khi sẽ không có thông báo lỗi. Tôi thường nghe mọi người nói về std :: vector không an toàn thread, đây có phải là một trong những trường hợp không? Tôi đang sử dụng Visual Studio 2008, thúc đẩy thread, kích thước của vector là cố định. Bất cứ ai cũng có thể cung cấp một số lời khuyên về cách sử dụng std :: vector trong một ứng dụng đa luồng.

  1. First-cơ hội ngoại lệ tại 0x7688b9bc trong ETP.exe: Microsoft C++ ngoại lệ: std :: out_of_range tại vị trí bộ nhớ 0x02d8f7bc ..
  2. First-cơ hội ngoại lệ tại 0x00e916e0 trong ETP.exe: 0xc0000005: Truy cập vị trí đọc vi phạm 0x00000008.
  3. Second Chance Assertion Failed: File c: \ program files (x86) \ visual studio microsoft 9.0 \ vc \ bao gồm vector \, dòng thứ hai Chance Assertion Failed: File c: \ program files (x86) \ microsoft thị giác studio 9.0 \ vc \ include \ vector98

Cảm ơn.

+0

vectơ không an toàn, nếu bạn cố gắng viết cùng lúc với các chủ đề khác nhau thì nó sẽ bị hỏng. Bạn đang khóa nó mặc dù, và không có mã khác để xem cách bạn đang sử dụng nó, nó là không thể nói những gì có thể sẽ sai. Mã đặc biệt này của chính nó có vẻ ổn. – Jarryd

+0

Ngoài chủ đề an toàn, có lẽ bạn cũng cần phải tính đến chuỗi trong đó các chủ đề của bạn truy cập vào vectơ, Nếu một luồng đang đọc từ vectơ thì bạn nên đảm bảo luồng khác đã ghi vào vectơ trước khi nó hoặc ít nhất mã phải xử lý điều kiện mà vectơ chưa được ghi vào. –

+0

@ Jarryd bạn nghi thức, trong đoạn mã này có vẻ như anh ta đang khóa vectơ bằng cách sử dụng mutex, nếu anh ta làm như vậy, thì nó sẽ không gây ra vấn đề gì, để biết chi tiết chúng ta cần phải xem mã hoàn chỉnh –

Trả lời

22

Thực ra, nó là hoàn toàn vô nghĩa với trạng thái X là hoặc không an toàn cho luồng! Bạn cần phải đủ điều kiện cho loại sử dụng. Ví dụ, hầu như không có bất kỳ lớp nào sẽ được "thread-safe" khi nó được sử dụng bằng cách nào đó trong một thread và bị phá hủy trong một thread khác.

Điều đó nói rằng, tuyên bố rằng std::vector<T> không an toàn theo chủ đề, độc lập với tần suất lặp lại, là sai. Tuy nhiên, có vẻ như hầu hết mọi người không hiểu và cũng không đánh giá cao sự đảm bảo an toàn luồng. std::vector<T> có chủ đề an toàn theo nghĩa sau:

  • Bạn có thể đọc đối tượng vectơ từ nhiều chủ đề cùng một lúc.
  • Nếu có một chủ đề thay đổi đối tượng vectơ, sẽ không có người đọc hoặc người viết đồng thời.
  • Truy cập vào đối tượng vectơ không ảnh hưởng đến các đối tượng vector khác.

Điều này áp dụng cho cấu trúc vectơ. Truy cập vào đối tượng chứa được ràng buộc với bất kỳ quy tắc được áp đặt trên chúng. Đây rõ ràng không phải là đảm bảo an toàn luồng mà nhiều người có trong đầu nhưng mọi thứ mạnh mẽ hơn sẽ không hoạt động với giao diện vùng chứa.

+0

cảm ơn lời khuyên của bạn. Bây giờ tôi thấy rõ hơn. – 2607

+0

Xin lỗi, nhưng hoàn toàn không đồng ý với bạn, thread-safe là một định nghĩa đã biết rằng việc triển khai phải đảm bảo đồng thời (thread) bảo vệ nó được chia sẻ các khu vực để tránh xung đột, điều này có nghĩa là một lớp là thread an toàn hay không, nói rằng nó phụ thuộc vào việc sử dụng có nghĩa là nó không an toàn thread !, làm thế nào có thể là câu trả lời đúng? – Cross

+0

Bạn có thể đọc đồng thời nhiều chuỗi. Có - miễn là một rào cản bộ nhớ phát hành diễn ra sau lần sửa đổi cuối cùng và một rào cản bộ nhớ có được kết hợp đã xảy ra trên tất cả các chủ đề đọc ... – Persixty

4

Bạn gọi số ptrVector->size() mà không khóa trước. Điều này có thể dễ dàng là nguyên nhân của vấn đề của bạn. Đảm bảo khóa vectơ của bạn trước bất kỳ lần đọc hoặc ghi nào.

+1

Anh ta nói rằng kích thước vectơ được cố định, do đó không gây ra vấn đề gì. Tuy nhiên, vì chúng tôi không có nhiều mã hơn, chúng tôi không biết liệu anh ấy có thêm mã theo cách không an toàn mà không biết. – Jarryd

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