Valgrind --tool = drd를 사용하여 Boost :: thread를 사용하는 응용 프로그램을 검사하고 있습니다. 기본적으로 응용 프로그램은 소켓 연결을 통한 입력을 기반으로 "Book"값 세트를 "Kehai"값으로 채 웁니다.경쟁 조건이 발생하는 위치를 파악할 수 없습니다.
별도의 스레드에서 사용자는 연결하여 책을 보낼 수 있습니다.
매우 간단합니다. 책을 직렬화하는 위치에 boost :: mutex :: scoped_lock을 사용하여 책 데이터를 지우는 위치는 경쟁 조건을 방지하는 데 충분해야합니다. datagetting 스레드 각각의 스레드를 송신 데이터라고
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;
}
클리어() 함수와 copyChangedKehaiToString() 함수 다음은 코드이다. 또한 , 메모 등, 클래스 도서 :
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;
};
사용 Valgrind의 --tool = DRD, 나는 그런 아래와 같이 경쟁 조건 오류를 얻을 :
==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)
내 인생 , 나는 경쟁 조건이 어디에 있는지 알 수 없다. 내가 말할 수있는 한, kehai를 지우는 것은 뮤텍스를 취한 후에 만 이루어지며, 똑같은 것은 문자열에 복사하는 것과 마찬가지입니다. 누군가이 문제의 원인이 될 수있는 아이디어가 있습니까?
감사합니다.
valdo, 업데이트 해 주셔서 감사합니다. 네, 똑같은 문제 같아요. 모든 것을 C 스타일 문자열로 전환하면 오류가 사라집니다. – Nik
그럼에도 불구하고 유용한 게시물입니다. 이제 Valgrind로 내 응용 프로그램을 테스트한다고 생각합니다. 멀티 스레딩을 많이 사용합니다. 문자열 정보 : "C 스타일 문자열"로 전환하면 문제가 사라집니다. 하지만 "C 스타일 문자열"이라고 부르는 것은 무엇입니까? 보다 정확하게 - 그들의 조작 및 수명에 대한 귀하의 정책은 무엇입니까? 문자열이 참조 횟수에 상관없이 문제가 사실과 관련 있다고 생각합니다. 의미 - 한 문자열을 다른 문자열에 할당 할 때 실제로 문자열의 복사본을 만들거나 동일한 문자열을 할당합니까? 참조 카운팅 된 경우 - 스레드로부터 안전합니까? – valdo
STL은 올바르게 잠 그거나 다중 스레드 읽기를 수행하는 경우 스레드에서 스레드를 사용하는 것이 문제가되지 않는다는 점에서 스레드 안전성이 있어야합니다. – Nikko