C++ 条件变量和唯一锁对线程安全列表的作用
我试图使用条件变量和唯一锁来创建线程安全列表。但是,我遇到了一些问题,列表操作似乎不是线程安全的 我已经创建了一个C++ 条件变量和唯一锁对线程安全列表的作用,c++,multithreading,C++,Multithreading,我试图使用条件变量和唯一锁来创建线程安全列表。但是,我遇到了一些问题,列表操作似乎不是线程安全的 我已经创建了一个原子标记来测试它是否是线程安全的。 基本上,当我操作列表时,我将首先检查是否设置了原子标志,并在列表操作完成时清除原子标志 在我看来,原子标志是在互斥保护下运行的,所以每次当我测试并设置原子标志时,我应该看到初始值应该是false,但当我运行测试代码时,我发现情况并非如此 有谁能帮我指出代码的错误,为什么列表操作在条件变量的保护下不是线程安全的 谢谢 测试代码如下所示: using
原子标记
来测试它是否是线程安全的。基本上,当我操作列表时,我将首先检查是否设置了原子标志,并在列表操作完成时清除原子标志 在我看来,原子标志是在互斥保护下运行的,所以每次当我测试并设置原子标志时,我应该看到初始值应该是false,但当我运行测试代码时,我发现情况并非如此 有谁能帮我指出代码的错误,为什么列表操作在条件变量的保护下不是线程安全的 谢谢 测试代码如下所示:
using namespace std;
//list element
class myitem
{
public:
myitem() { val = -1; };
myitem(int n, int c){ val = n; chr = c; };
int val;
char chr;
};
// mutex and condition variable to protect the list.
std::mutex mymtx;
condition_variable mycv;
// the list to be protected
std::list<myitem> mylist;
// the atomic flag to test.
std::atomic_flag testlk = ATOMIC_FLAG_INIT;
void datagenthread(char c)
{
int n = 10*1000*1000;
while(n >0)
{
myitem item(n, c);
{
unique_lock<mutex> lk(mymtx); // get the lock
if( testlk.test_and_set() != false) { // test the atomic flag
cout<<"error in thread"<<c<<" for test lock"<<endl;
}
mylist.push_back(item);
testlk.clear(); // clear the atomic before unlock.
}
mycv.notify_one();
n--;
}
}
void datareadthread()
{
int count = 0;
int readc = 0;
while ( count <2) {
{
unique_lock<mutex> lk(mymtx); // acquire lock
while ( mylist.size() <= 0) {
mycv.wait(lk); // block until the thread get notified and get lock again.
}
if( testlk.test_and_set()!= false) {// test the atomic flag.
cout<<"error in reader thread"<<endl;
}
myitem readitem;
readitem = mylist.front();
mylist.pop_front();
readc++;
if ( readitem.val == 1)
{
cout<<" get last one last item form a thread,"<<endl;
count++;
}
testlk.clear(); // clear the atomic flag before unlock
}//unique_lock destruct
}//end while
}
int main()
{
std::thread cons( datareadthread);
std::thread gen1( datagenthread, 'a');
std::thread gen2( datagenthread, 'b');
gen1.join();
gen2.join();
cons.join();
return 0;
}
使用名称空间std;
//列表元素
类myitem
{
公众:
myitem(){val=-1;};
myitem(intn,intc){val=n;chr=c;};
int-val;
char-chr;
};
//互斥和条件变量来保护列表。
std::mutex mymtx;
条件变量mycv;
//要保护的列表
std::列表mylist;
//要测试的原子标志。
std::atomic_flag testlk=atomic_flag_INIT;
void datagenthread(char c)
{
int n=10*1000*1000;
而(n>0)
{
我的项目(n,c);
{
unique_lock lk(mymtx);//获取锁
如果(testlk.test_和_set()!=false){//测试原子标志
couttestlk
默认构造函数将其初始化为未指定状态,因此在第一次迭代时,初始值不是false
。您应该使用如下清除状态初始化它:
std::atomic_flag testlk = ATOMIC_FLAG_INIT;
我已经找到了原因,似乎我链接了一些错误的lib,这导致互斥锁/条件变量无法正常工作。这里没有看到任何线程错误我在arm linux平台下构建了它,并得到了很多错误,比如:读卡器线程错误读卡器线程错误读卡器线程错误读卡器线程错误读卡器线程错误读卡器线程错误读卡器线程错误读卡器线程错误In threada for test lock error in threada for test lock error in threada for test lock如何构建它?我已更改代码以初始化atomic_标志,但问题仍然存在。我正在arm Linux平台下运行代码。