2

自从我的上一个问题关闭以来重新发布此内容..这次我试图更好地解释它...如果您需要进一步澄清,请告诉我:

我有一个带有函数 doSomething(int count) 的类 A 在 A 类中,我想打开 100 个线程,每个线程调用函数 doSomething() 并在每个线程中传入 1-100 的计数。

这意味着......当第一个线程调用这个函数时,它应该调用 doSomething(1),第二个线程应该调用 doSomething(2) 等等......

这就是我的代码的样子:

struct input {
  A* in;
  int count;
};


myFunc(void* data)
{
  input* tP = (input*) data;
  A* obj = tP->in;
  int ct = tP->count;
  obj->doSomething(ct);
}

class A {
  doSomething(int count);
  Thread2doSomething();
}

doSomething(int count)
{
  cout<<"Print value is"<<count;
}

Thread2doSomething()
{
   for (i = 1 to 100)
   {
      input myIN;
      myIN.in = this;
      myIN.count = i;
      beginthreadex(myFunc, &myIN);
   }
 }

我希望上面的代码会在这里产生 100 个线程..当它调用 doSomething(); 时,每个线程都会有一个新的计数值 1,2,3...100;

在新线程上每次调用 doSomething 都应该有一个不同的 count 值传递给它 - 1,2,3,...到 100。

但这不会发生。传递给它的计数值是非常随机的......通常它多次获得相同的值......并且根本没有得到一些值。有时传递给 doSomething 的计数值在所有线程中都是相同的......

调用看起来更像这样:doSOthing(4)、doSomething(4)、doSomething(7)、doSomething(10)、doSomething(10) 等等。

希望我已经澄清了事情......请建议。

4

2 回答 2

2

您的代码有两个问题。

一个问题出在Thread2doSomething()函数中:您将临时地址传递给beginthreadex(). 当函数退出时临时超出范围,并且线程正在访问一个不再存在的对象。

您有两种解决此问题的可能性:要么在退出之前等待所有线程完成Thread2DoSomething(),以便在线程完成工作之前不会破坏堆栈分配的对象,要么在堆(但如果您使用原始指针,请不要忘记释放它们)。

第二问题是您将相同的输入传递给所有线程并在它们访问它时(在for循环内)对其进行修改,这引入了数据竞争。因此,您的程序具有Undefined Behavior

要解决此问题,您必须为每个线程创建一个新实例input,这样您就不会在线程尝试访问它时覆盖同一个对象。

最后,请记住,不能保证线程的执行顺序。即使您按特定顺序启动它们,您仍然可能会看到打印出的数字排列而不是有序序列 1..100。

于 2013-01-17T08:51:40.493 回答
0

您正在为所有线程重新使用一个实例。input当然,他们会从中获取随机数据。由于您无法更改的签名myFunc()(我认为它是由线程创建功能强制要求的),因此您必须使用动态分配:

Thread2doSomething()
{
   input *myIN;
   for (i = 1 to 100) {
     myIN = new input;
     myIN->in = this;
     myIN->count = i;
     beginthreadex(myFunc, myIN);
   }
}

myFunc(void* data)
{
  std::unique_ptr<input> tP(reinterpret_cast<input*>(data));
  A* obj = tP->in;
  int ct = tP->count;
  obj->doSomething(ct);
}

使用unique_ptrin将确保对象在终止myFunc()时被释放。myFunc()

于 2013-01-17T08:50:33.873 回答