我需要产生4个线程,基本上执行相同的操作,但每个线程都有不同的变量。因此,我调用:: CreateThread 4次,给出相同的threadProc和'this'作为参数。现在在threadProc中,我需要选择正确的变量来使用。我有一个对象向量,并且在每次CreateThread调用后立即将对象推入其中。
// at this point myVec has say, 2 items
HANDLE hThread = ::CreateThread( NULL, NULL, threadProc, (LPVOID)this, NULL, NULL );
myVecObj.threadHandle = hThread;
myVec.push_back(myVecObj); // myVec.Size = 3 now
DWORD CALLBACK myClass::threadProc(LPVOID lpContext)
{
myClass *pMyClass = (myClass *)lpContext;
int vecCount = pMyClass->myVec.size; // Is this 3??
char * whatINeed = (char*)pMyClass->myVec[vecCount-1].whatINeed;
}
我的疑问/问题是threadProc触发的速度有多快-它可以击败对myVec.push_back()的调用吗?这是我要介绍的比赛条件吗?我试图做出这样一个假设:当每个threadProc启动时(它们在不同的时间启动,而不是一个接一个地启动),我可以安全地获取类向量中的最后一个对象。
最佳答案
我需要产生4个线程,基本上执行相同的操作,但每个线程都有不同的变量。因此,我调用4次::CreateThread
,并给出相同的threadProc
和this
作为参数。
现在在threadProc
中,我需要选择正确的变量来使用。
为什么不向线程传递指向它需要作用的实际对象的指针?
我有一个对象向量,并且在每次CreateThread
调用后立即将对象推入其中。
这是错误的处理方式。是的,那是比赛条件。不仅由于明显的原因-线程可能在推送对象之前就开始运行-而且还因为对向量的任何推送都可能重新分配向量的内部数组,这对于已经获得指向该指针的线程来说是非常糟糕的向量中的数据。数据将在线程背后的内存中移动。
要解决此问题,您需要执行以下任一操作:
首先将所有对象推入向量,然后启动线程。您可以将指向每个向量元素的指针传递到其各自的线程。但这仅在由于上述原因而在任何线程运行时不再修改向量时才有效。
首先将线程以挂起状态启动,然后在将所有对象推入向量中之后恢复它们。这也要求您不再修改向量。这也意味着您必须将每个线程的索引传递给向量元素,而不是将其传递给该元素的指针。
完全删除向量(或至少将其更改为容纳对象指针而不是实际对象)。使用new
动态分配对象,并根据需要将这些指针传递给每个线程(也可以传递给向量)。在退出之前,让每个线程delete
其对象(并选择通过适当的同步将其从向量中删除)。
我的疑问/疑问是threadProc
发射多快
这完全取决于操作系统调度程序。
可以打败myVec.push_back()
的电话吗?
是的,这是有可能的。
这是我要介绍的比赛条件吗?
是。
我正在做假设
不要做假设!
当每个threadProc
开始时(它们在不同的时间开始,而不是一个接一个地开始),我可以安全地获取类向量中的最后一个对象。
这不是一个安全的假设。
关于c++ - CreateThread的threadProc竞争条件,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/51886427/