POSIX线程C中的本地数据

时间:2012-05-05 19:48:33

标签: c linux multithreading pthreads

我试图给每个线程一些特定于线程的数据;可以使用thread参数吗?

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

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 个答案:

答案 0 :(得分: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);

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

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

uintptr_t value = c1 + 10;

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

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

答案 1 :(得分:2)

  

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

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

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

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

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

首先 - 没有distinction between a thread and a process in the kernel in 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]));

等等。

答案 2 :(得分:1)

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

答案 3 :(得分:-2)

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

无论如何,我强烈建议您查看网站:

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