2

我在 VS .NET 2003 中的程序存在一些问题。

我最初编写了一个模块,该模块使用 pthread 库创建多个线程来处理某些内容。这在 VS .NET 2003 中正确运行。然后这个模块被其他人使用并集成到另一个更大的程序中。我不确定细节,但该程序创建了一个 GUI,允许用户选择一个选项来运行我的模块。

创建线程时,会传入一个值作为线程 id。我在 GUI 中的模块的问题是线程 id 的值对于所有线程都是 0,而在没有 GUI 的模块中线程 id 是正确的。

以下是在模块中创建线程的方式:

int64_t *tid[1000];
int64_t i = 0, rc;

for (i = 0 ; i < NUM_THREADS ; i++)
{
   tid[i] = (int64_t *) malloc(sizeof(int64_t));
   *tid[i] = i;
   rc = pthread_create(&pthread, &attr, function, (void *)tid[i]);
   Sleep(1);
   if(rc)
   {
      free(tid[i]);
      exit(1);
   }
   free(tid[i]);
}

我检查了两者的项目属性,下面列出了两个项目之间的唯一区别:

GUI - use managed extensions | my module (w/o GUI) - does not use managed extensions
In C/C++ preprocessor:
   GUI - WIN32;_DEBUG;_CONSOLE;WINDOWS | my module (w/o GUI) - none
In C/C++ Additional Options:
   GUI - /CLR | my module (w/o GUI) - no /CLR (error with /CLR: fatal error LNK1000: Internal error during BuildImage)

代码是一样的,所以我不明白为什么 GUI 的输出是错误的,除非使用托管扩展/clr 会有所不同?(我也不确定那些是什么。)

编辑添加输出线程 id 的代码部分:

void *function(void *input)
{
   int64_t threadid = *(int64_t *)input;
   printf("threadid = %ld\n", threadid);
   ...
}

请指教。

谢谢你。

问候,雷恩

4

1 回答 1

0

将 tid 传递给函数时,您似乎遇到了竞争条件 - 尝试删除 Sleep(1) 并改为使用线程空闲 tid。从您上面的评论来看,这似乎解决了这个问题。

要回答您的另一个问题,当 pthread_create 返回您的主线程时,新线程已创建(为操作系统中的线程分配的内存等)但可能尚未实际运行。设置 Sleep(1) 使新线程更有可能运行(强制主线程放弃时间片),但不能保证线程在主线程再次运行并调用 free(tid[i]); 之前得到 tid;

因此,让工作线程释放 tid 的想法 - 它将在它捡起后释放。

如果您将 tid 数组更改为 int64 数组并传递 &tid[i] 那么您将不需要 malloc/free 并且竞争条件也得到了解决 - 尽管这仅在您保证只有一个调用者的情况下才有效图书馆。

我希望这会有所帮助 - 正确处理线程可能很棘手,但值得付出努力!

于 2010-03-03T12:19:52.727 回答