3

我试图给每个线程一些线程特定的数据;这可以使用线程参数来完成吗?

那么在创建线程时,我传递了一个变量,在线程函数中,我改变了它的值并将其用作每个线程的特定数据?

int main(void){
    ...
    int Tparam = 0;
    ...
    rc = pthread_create(&threads[c1], NULL, Thread_Pool, (void *)Tparam);
    ...
}

然后在 Thread_Pool 函数中我像这样使用它

void *Thread_Pool(void *param){
    int id;
    id = (int) param;
    id = value; // can this value be a specific value for this thread?
}
4

4 回答 4

4

如果您展示了如何Tparam声明它可能会有所帮助。

但是,如果您希望每个线程都有自己的空间来存储一些数据,那么您可以安排将该空间作为函数的参数传递给线程。例如:

enum { NTHREADS = 10 };

struct TLS_Data
{
    int   id;
    char  buffer[2048];
    size_t index;
} data[NTHREADS];

for (int c1 = 0; c < NTHREADS; c1++)
{
    data[c1].index = c1;
    data[c1].id = 0;
    data[c1].buffer[0] = '\0';
    int rc = pthread_create(&threads[c1], NULL, Thread_Pool, &data[c1]);
    ...handle errors, etc...
}

注意 ; 的最后一个参数没有强制转换pthread_create()void *当范围内有原型时,没有必要将指针转换为。

在您的Thread_Pool中,您似乎想将参数视为整数;这也可以做到。传递一个指向整数的指针是最干净的;如果你真的坚持,你可以直接传递整数值:

uintptr_t value = c1 + 10;

rc = pthread_create(&threads[c1], NULL, Thread_Pool, (void *)value);

因为valueis的类型uintptr_t,你知道它能够保存一个 void 指针,所以它为你提供了最大的工作机会。但是您正在与类型系统作斗争,这使得编写干净的代码变得更加困难。

Thread_Pool()要注意的一件事是,如果应该看到不同的值,您需要确保传递给线程函数(在您的示例中)的数据不会在线程之间共享。无法保证线程执行的顺序,所以如果你犯了如下错误:

uintptr_t value = c1 + 10;

rc = pthread_create(&threads[c1], NULL, Thread_Pool, &value);

(并且该代码处于循环中),则无法保证每个线程函数会看到什么。要小心!

于 2012-05-05T20:14:44.257 回答
2

这个值可以是这个线程的特定值吗?

嗯,首先,你可能想要这个:

int id = *((int*) param);

即你需要在给它一个类型的指针后取消引用参数指针。您不能取消引用 void 指针,因为 void没有 type

现在 - 这里发生了什么?好吧,首先我们需要了解一下线程。

首先 - Linux 内核中的线程和进程没有区别。绝对没有。它们都是执行或任务的上下文。但是,一个主要区别是线程任务共享数据——线程堆栈除外。阅读该答案,您可以看到线程与其创建者共享几乎所有其他内容。

但是,堆栈不能共享。堆栈跟踪许多事情,例如程序在执行方面的位置、某些系统上的返回值和函数参数。在函数内声明的自动存储持续时间变量(没有任何其他修饰符的变量)也存储在堆栈中。

这意味着 - 在线程函数中声明的变量对于该线程是唯一的。因此,鉴于您的功能:

void threadfunc(void* param)
{
    int id = /* ??? */
}

每个线程都有自己的int id本地存储副本,该副本将在线程期间持续存在。您可以通过值或指向它的指针将其传递给后续函数。

因此,调用是完全有效的:

int tParam[] = {1,2,3};

rc = pthread_create(&threads[1], NULL, Thread_Pool, (void *)&(tParam[1]));
rc = pthread_create(&threads[2], NULL, Thread_Pool, (void *)&(tParam[2]));
rc = pthread_create(&threads[3], NULL, Thread_Pool, (void *)&(tParam[3]));

等等。

于 2012-05-05T20:12:20.897 回答
1

您可以调用 pthread_self()。它返回一个唯一的线程 ID。请参阅 juampa 推荐的 LLNL URL 上的 API 参考。

于 2012-05-05T20:09:39.947 回答
-2

我不懂你的问题; 我仍然无法弄清楚你真正想做什么。

无论如何,我强烈建议您检查以下网站:

它们很短,但仍然包含您可能需要开始使用的大部分内容。

于 2012-05-05T20:03:52.123 回答