linux C语言中的POSIX线程本地数据

sf6xfgos  于 2022-12-03  发布在  Linux
关注(0)|答案(4)|浏览(124)

我尝试为每个线程提供一些特定于线程的数据;可以使用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?
}
v6ylcynt

v6ylcynt1#

如果您展示如何声明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,你知道它能够容纳一个void指针,所以它给了你最大的机会让事情正常工作,但是你在与类型系统作斗争,这使得编写干净的代码变得更加困难。
需要注意的一点是,如果线程应该看到不同的值,则需要确保传递给线程函数的数据(示例中为Thread_Pool())不会在线程之间共享。无法保证线程执行的顺序,因此,如果您犯了以下错误:

uintptr_t value = c1 + 10;

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

(and代码在循环中),那么就不能保证每个线程函数会看到什么。

i2loujxw

i2loujxw2#

can this value be a specific value for this thread ?
Well, first thing's first, you probably want this:

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

i.e. you need to dereference the parameter pointer after giving it a pointer with a type. You cannot dereference a void pointer, because void has no type.
Now - what happens here? Well, first we need to understand threads a bit.
Firstly - there is no distinction between a thread and a process in the kernel in Linux . Absolutely none. They're all contexts of execution, or tasks. However, one major difference is that threaded tasks share data - except for thread stacks. Reading that answer, you can see that a thread shares almost everything else with its creator.
A stack, however, must not be shared. Stacks track a number of things, for example where the program is up to execution-wise, return values and function parameters on some systems. Automatic storage duration variables - those without any other modifier - declared inside a function are also stored on the stack.
Which means - variables declared inside your thread function are unique to that thread. So, given your function:

void threadfunc(void* param)
{
    int id = /* ??? */
}
  • Each thread* has its own copy of int id stored locally that will last for the duration of the thread. You can pass this to subsequent functions by value, or a pointer to it.

As such, it is perfectly valid to call:

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

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

and so on.

jtjikinw

jtjikinw3#

你可以调用pthread_self(),它返回一个唯一的线程id,参见juampa推荐的LLNL URL上的API参考。

deyfvvtc

deyfvvtc4#

我不明白你的问题;我还是不知道你到底想做什么。
在任何情况下,我强烈建议您检查网站:

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

相关问题