Andna
Andna

Reputation: 6689

Linux Pthread library, thread arguments

If I create thread using Pthread library under Linux, I need to use function pthread_create, as one of the arguments it takes void *, so I can pass a pointer to something, so my thread routine can get access to it, but is it safe to do something like this

{//some scope
    int a=5//scope variable
    pthread_create(&id,NULL,some_function,(void*)a);
}//end of scope

and in my routine:

void *some_function(void *_arg)
{
    int a=(int)arg;
    return NULL;
}

I want to do something like this, so I can keep the value of a variable on stack so I can access it from my thread routine but I don't want to create struct for single variable or manually allocate memory.

I will be creating few threads like this, so I wanted to know if in situation like this I can get by and don't use list or dynamic array.

Upvotes: 1

Views: 1239

Answers (2)

Tanner Sansbury
Tanner Sansbury

Reputation: 51881

In this case, it is safe to push the value of a onto some_function's stack via the arg argument because void*'s size is large enough to support the value of an integer.

Upvotes: 1

R.. GitHub STOP HELPING ICE
R.. GitHub STOP HELPING ICE

Reputation: 215259

What you're doing is perfectly safe in the real world: conversion between int and void * is not undefined behavior, it's implementation-defined, and all implementations define it in the natural, sane way. It's also the only efficient way to pass single-integer arguments to a new thread. Other approaches all require expensive synchronization, either via explicit locking or by using malloc in the original thread and free in the new thread (which has implicit synchronization cost hidden in the malloc/free implementation).

One thing you will discover, however, is that some compilers issue warnings for the conversion. This is because of old broken code that assumes int can represent the full range of values of void *; the compiler is unable to distinguish between the (valid) practice of storing an int in a void *, and the (invalid) practice of storing a void * in an int. As a solution, you might want to use intptr_t instead of int, which will avoid the warning. If your original variables are int, simply adding an extra intermediate cast through intptr_t will avoid the warnings.

Upvotes: 4

Related Questions