C中的POSIX线程本地数据

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

所以当创build线程时,我传递一个variables,并且在线程函数中,我更改它的值并将其用作每个线程的特定数据?

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? } 

如果你展示了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()的最后一个参数没有pthread_create() ; 当范围内有原型时,不需要将指针转换为void *

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

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

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

有一点需要注意的是,如果需要看到不同的值,则需要确保传递给线程函数(在您的示例中为Thread_Pool() )的数据不在线程之间共享。 线程执行的顺序不能保证,所以如果你犯了一个错误,比如:

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

(并且该代码在循环中),那么就不能保证每个线程函数会看到什么。 要小心!

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

那么,首先,你可能想要这个:

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

给它一个带有类型的指针 ,你需要解引用参数指针。 你不能解引用void指针,因为void 没有类型

现在 – 这里发生了什么? 那么,首先我们需要了解一些线程。

首先 – 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])); 

等等。

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

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

无论如何,我会强烈建议你检查这些网站:

他们很短,但仍然包含大部分你可能需要开始的东西。