Tôi đang sử dụng Valgrind --tool = drd để kiểm tra ứng dụng của tôi sử dụng Boost :: thread. Về cơ bản, ứng dụng sẽ điền một tập hợp các giá trị "Sách" với các giá trị "Kehai" dựa trên đầu vào thông qua kết nối ổ cắm.Không thể biết được tình trạng chủng tộc đang xảy ra ở đâu
Trên một chuỗi riêng biệt, người dùng có thể kết nối và nhận sách gửi cho họ.
Nó khá đơn giản, vì vậy tôi đã tìm cách sử dụng tăng :: mutex :: scoped_lock trên vị trí tuần tự hóa sách và vị trí xóa dữ liệu sách phải đủ để ngăn chặn mọi điều kiện chủng tộc. Đây là mã:
void Book::clear()
{
boost::mutex::scoped_lock lock(dataMutex);
for(int i =NUM_KEHAI-1; i >= 0; --i)
{
bid[i].clear();
ask[i].clear();
}
}
int Book::copyChangedKehaiToString(char* dst) const
{
boost::mutex::scoped_lock lock(dataMutex);
sprintf(dst, "%-4s%-13s",market.c_str(),meigara.c_str());
int loc = 17;
for(int i = 0; i < Book::NUM_KEHAI; ++i)
{
if(ask[i].changed > 0)
{
sprintf(dst+loc,"A%i%-21s%-21s%-21s%-8s%-4s",i,ask[i].price.c_str(),ask[i].volume.c_str(),ask[i].number.c_str(),ask[i].postTime.c_str(),ask[i].status.c_str());
loc += 77;
}
}
for(int i = 0; i < Book::NUM_KEHAI; ++i)
{
if(bid[i].changed > 0)
{
sprintf(dst+loc,"B%i%-21s%-21s%-21s%-8s%-4s",i,bid[i].price.c_str(),bid[i].volume.c_str(),bid[i].number.c_str(),bid[i].postTime.c_str(),bid[i].status.c_str());
loc += 77;
}
}
return loc;
}
Hàm clear() và hàm copyChangedKehaiToString() được gọi trong chuỗi gửi dữ liệu và chuỗi gửi dữ liệu tương ứng. Ngoài ra, như một ghi chú, lớp Book:
struct Book
{
private:
Book(const Book&); Book& operator=(const Book&);
public:
static const int NUM_KEHAI=10;
struct Kehai;
friend struct Book::Kehai;
struct Kehai
{
private:
Kehai& operator=(const Kehai&);
public:
std::string price;
std::string volume;
std::string number;
std::string postTime;
std::string status;
int changed;
Kehai();
void copyFrom(const Kehai& other);
Kehai(const Kehai& other);
inline void clear()
{
price.assign("");
volume.assign("");
number.assign("");
postTime.assign("");
status.assign("");
changed = -1;
}
};
std::vector<Kehai> bid;
std::vector<Kehai> ask;
tm recTime;
mutable boost::mutex dataMutex;
Book();
void clear();
int copyChangedKehaiToString(char * dst) const;
};
Khi sử dụng valgrind --tool = DRD, tôi nhận được lỗi tình trạng chủng tộc như hình dưới đây:
==26330== Conflicting store by thread 1 at 0x0658fbb0 size 4
==26330== at 0x653AE68: std::string::_M_mutate(unsigned int, unsigned int, unsigned int) (in /usr/lib/libstdc++.so.6.0.8)
==26330== by 0x653AFC9: std::string::_M_replace_safe(unsigned int, unsigned int, char const*, unsigned int) (in /usr/lib/libstdc++.so.6.0.8)
==26330== by 0x653B064: std::string::assign(char const*, unsigned int) (in /usr/lib/libstdc++.so.6.0.8)
==26330== by 0x653B134: std::string::assign(char const*) (in /usr/lib/libstdc++.so.6.0.8)
==26330== by 0x8055D64: Book::Kehai::clear() (Book.h:50)
==26330== by 0x8094A29: Book::clear() (Book.cpp:78)
==26330== by 0x808537E: RealKernel::start() (RealKernel.cpp:86)
==26330== by 0x804D15A: main (main.cpp:164)
==26330== Allocation context: BSS section of /usr/lib/libstdc++.so.6.0.8
==26330== Other segment start (thread 2)
==26330== at 0x400BB59: pthread_mutex_unlock (drd_pthread_intercepts.c:633)
==26330== by 0xC59565: pthread_mutex_unlock (in /lib/libc-2.5.so)
==26330== by 0x805477C: boost::mutex::unlock() (mutex.hpp:56)
==26330== by 0x80547C9: boost::unique_lock<boost::mutex>::~unique_lock() (locks.hpp:340)
==26330== by 0x80949BA: Book::copyChangedKehaiToString(char*) const (Book.cpp:134)
==26330== by 0x80937EE: BookSerializer::serializeBook(Book const&, std::string const&) (BookSerializer.cpp:41)
==26330== by 0x8092D05: BookSnapshotManager::getSnaphotDataList() (BookSnapshotManager.cpp:72)
==26330== by 0x8088179: SnapshotServer::getDataList() (SnapshotServer.cpp:246)
==26330== by 0x808870F: SnapshotServer::run() (SnapshotServer.cpp:183)
==26330== by 0x808BAF5: boost::_mfi::mf0<void, RealThread>::operator()(RealThread*) const (mem_fn_template.hpp:49)
==26330== by 0x808BB4D: void boost::_bi::list1<boost::_bi::value<RealThread*> >::operator()<boost::_mfi::mf0<void, RealThread>, boost::_bi::list0>(boost::_bi::type<void>, boost::_mfi::mf0<void, RealThread>&, boost::_bi::list0&, int) (bind.hpp:253)
==26330== by 0x808BB90: boost::_bi::bind_t<void, boost::_mfi::mf0<void, RealThread>, boost::_bi::list1<boost::_bi::value<RealThread*> > >::operator()() (bind_template.hpp:20)
==26330== Other segment end (thread 2)
==26330== at 0x400B62A: pthread_mutex_lock (drd_pthread_intercepts.c:580)
==26330== by 0xC59535: pthread_mutex_lock (in /lib/libc-2.5.so)
==26330== by 0x80546B8: boost::mutex::lock() (mutex.hpp:51)
==26330== by 0x805473B: boost::unique_lock<boost::mutex>::lock() (locks.hpp:349)
==26330== by 0x8054769: boost::unique_lock<boost::mutex>::unique_lock(boost::mutex&) (locks.hpp:227)
==26330== by 0x8094711: Book::copyChangedKehaiToString(char*) const (Book.cpp:113)
==26330== by 0x80937EE: BookSerializer::serializeBook(Book const&, std::string const&) (BookSerializer.cpp:41)
==26330== by 0x808870F: SnapshotServer::run() (SnapshotServer.cpp:183)
==26330== by 0x808BAF5: boost::_mfi::mf0<void, RealThread>::operator()(RealThread*) const (mem_fn_template.hpp:49)
==26330== by 0x808BB4D: void boost::_bi::list1<boost::_bi::value<RealThread*> >::operator()<boost::_mfi::mf0<void, RealThread>, boost::_bi::list0>(boost::_bi::type<void>, boost::_mfi::mf0<void, RealThread>&, boost::_bi::list0&, int) (bind.hpp:253)
Đối với cuộc sống của tôi , tôi không thể biết được tình trạng của cuộc đua ở đâu. Theo như tôi có thể nói, thanh toán bù trừ kehai chỉ được thực hiện sau khi đã thực hiện mutex, và điều tương tự cũng đúng với việc sao chép nó vào một chuỗi. Có ai có bất kỳ ý tưởng gì có thể gây ra điều này, hoặc nơi tôi nên nhìn?
Cảm ơn bạn.
valdo, cảm ơn bạn đã cập nhật. Vâng, tôi nghĩ rằng đó chính là vấn đề chính xác. khi tôi chuyển mọi thứ thành chuỗi kiểu C, các lỗi đã biến mất. – Nik
Tuy nhiên, đó là một bài đăng hữu ích. Bây giờ tôi nghĩ rằng để thử nghiệm các ứng dụng của tôi với Valgrind, tôi sử dụng đa luồng rất nhiều. Giới thiệu về chuỗi: Bạn nói rằng sự cố sẽ biến mất khi bạn chuyển sang "Chuỗi kiểu C". Nhưng những gì bạn gọi là "chuỗi kiểu C"? Chính xác hơn - chính sách của bạn về thao tác và tuổi thọ của họ là gì. Tôi tin rằng vấn đề có liên quan đến thực tế nếu các chuỗi của bạn được tính tham chiếu hay không. Có nghĩa là - khi bạn gán một chuỗi cho một chuỗi khác: bạn có thực sự tạo một bản sao của chuỗi của mình hay bạn phân bổ một chuỗi khác giống với chuỗi đó không? Và nếu nó được tính tham chiếu - nó có an toàn không? – valdo
STL được cho là an toàn theo luồng theo nghĩa là không phải là vấn đề khi sử dụng chúng với chuỗi nếu bạn khóa chính xác hoặc nếu bạn chỉ thực hiện đọc nhiều luồng – Nikko