Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

POSIX thread local data in C

I am trying to give each thread some thread-specific data; can this be done using the thread parameter?

So when creating the thread, I pass a variable, and in the thread function, I change its value and use it as a specific data for each thread?

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

then in the Thread_Pool function I use it like this

void *Thread_Pool(void *param){
    int id;
    id = (int) param;
    id = value; // can this value be a specific value for this thread?
}
like image 336
CodeRed Avatar asked Nov 30 '25 22:11

CodeRed


1 Answers

It might help if you showed how Tparam was declared.

However, if you want each thread to have its own space in which to store some data, then you can arrange to pass that space into the thread as the argument to the function. For example:

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

Note the absence of a cast on the last argument to pthread_create(); it isn't necessary to convert a pointer to void * when there's a prototype in scope.

In your Thread_Pool, you seem to want to treat the parameter as an integer; that can be done too. It is most cleanly done passing a pointer to the integer; you can pass the integer value directly if you really insist:

uintptr_t value = c1 + 10;

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

Because the type of value is uintptr_t, you know it is capable of holding a void pointer, and so it gives you the maximum chance of things working. But you're fighting the type system, which makes it harder to write clean code.

The one thing to be aware of is that you need to ensure that the data passed to the thread function (Thread_Pool() in your example) is not shared between threads if they are supposed to see different values. There is no guarantee of the order of thread execution, so if you made a mistake such as:

uintptr_t value = c1 + 10;

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

(and that code was in a loop), then there'd be no guarantee about what each thread function would see. Be cautious!

like image 177
Jonathan Leffler Avatar answered Dec 03 '25 14:12

Jonathan Leffler