对于std::list l,
在线程1中,我做到了
l.push_back
在thread2中,我做到了
而(l.size()> 1)l.pop_front()
当这两个线程同时运行时,我发生了数据争夺。
令我感到困惑的是,我在pop_front之前检查了l.size是否大于一个,
因此,在push_back时,在任何情况下都不会将对象推回Null的前身,
那我为什么不明白为什么要进行数据竞赛呢。
下面是我测试中的代码:
#include <windows.h>
#include <list>
using namespace std;
HANDLE gsem = CreateSemaphore(NULL, 2, 2, NULL);
unsigned long __stdcall threadPoc(list<int>* l);
unsigned long __stdcall threadPoc2(list<int>* l);
int main()
{
std::list<int> l;
unsigned long a1, a2;
HANDLE t[2];
t[0] = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)threadPoc, &l, 0, &a1);
t[1] = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)threadPoc2, &l, 0, &a2);
ReleaseSemaphore(gsem, 2, NULL);
WaitForMultipleObjects(2, t, TRUE, INFINITE);
return 0;
}
bool exf = false;
unsigned long __stdcall threadPoc(list<int>* l)
{
WaitForSingleObject(gsem, INFINITE);
for (int i=0; i<100000; i++)
l->push_back(i);
exf = true;
return 0;
}
unsigned long __stdcall threadPoc2(list<int>* l)
{
WaitForSingleObject(gsem, INFINITE);
while (l->size()>1 || !exf)
l->pop_front();
return 0;
}
最佳答案
并发性是一个大话题,首先,我请您阅读Anthony Williams的“C++并发性”,在读完本书之后,您几乎可以理解所有内容。
首先,请记住一件事,当一个线程被写入,而另一线程被读取/写入同一对象时,总是存在冲突。
其次,对于您的特定问题,显然有几个冲突的地方。