我需要产生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,并给出相同的threadProcthis作为参数。
  
  现在在threadProc中,我需要选择正确的变量来使用。


为什么不向线程传递指向它需要作用的实际对象的指针?


  我有一个对象向量,并且在每次CreateThread调用后立即将对象推入其中。


这是错误的处理方式。是的,那是比赛条件。不仅由于明显的原因-线程可能在推送对象之前就开始运行-而且还因为对向量的任何推送都可能重新分配向量的内部数组,这对于已经获得指向该指针的线程来说是非常糟糕的向量中的数据。数据将在线程背后的内存中移动。

要解决此问题,您需要执行以下任一操作:


首先将所有对象推入向量,然后启动线程。您可以将指向每个向量元素的指针传递到其各自的线程。但这仅在由于上述原因而在任何线程运行时不再修改向量时才有效。
首先将线程以挂起状态启动,然后在将所有对象推入向量中之后恢复它们。这也要求您不再修改向量。这也意味着您必须将每个线程的索引传递给向量元素,而不是将其传递给该元素的指针。
完全删除向量(或至少将其更改为容纳对象指针而不是实际对象)。使用new动态分配对象,并根据需要将这些指针传递给每个线程(也可以传递给向量)。在退出之前,让每个线程delete其对象(并选择通过适当的同步将其从向量中删除)。



  我的疑问/疑问是threadProc发射多快


这完全取决于操作系统调度程序。


  可以打败myVec.push_back()的电话吗?


是的,这是有可能的。


  这是我要介绍的比赛条件吗?


是。


  我正在做假设


不要做假设!


  当每个threadProc开始时(它们在不同的时间开始,而不是一个接一个地开始),我可以安全地获取类向量中的最后一个对象。


这不是一个安全的假设。

关于c++ - CreateThread的threadProc竞争条件,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/51886427/

10-11 16:50