Иногда обобщение проблемы помогает увидеть решение. Преобразование int
в void *
- старый прием, позволяющий избежать выделения памяти. Иногда вам просто нужно настроить поток, который будет работать не только с int.
Обычный подход, который я использую для настройки pthreads, заключается в calloc
некоторой структуре или даже в пространстве для одного значения (например, unsigned long long
), передаче его в аргумент pthread и его использовании в моей функции потока перед тем, как while (1)
логики основного потока, затем free
.
Это позволяет вам передавать столько или мало, сколько вы хотите, всегда в порядке, независимо от размера того, что вы передаете, и не пытается пихать значения в указатели.
typedef struct {
unsigned long long large_serial_number;
const char *my_name;
pthread_t caller_thread;
} fun_thread_args_t;
static void* _fun_thread_run(void *arg) {
// Get our thread args from the dynamically allocated thread args passed-in
fun_thread_args_t *thread_args = (fun_thread_args_t *)arg;
bool done = false;
while (!done) {
// Use args here in your thread loop
...
}
// Free incoming args pointer before exiting the thread loop.
free(arg);
return NULL;
}
static pthread_t *_launch_fun_thread(pthread_t *thread, unsigned long long serial_number, const char *name) {
// TODO: Of course, error-handle all the return values properly ;)
// Allocate and prepare args for the thread
fun_thread_args_t *args = calloc(1, sizeof(args));
args->caller_thread = pthread_self();
args->large_serial_number = serial_number;
args->my_name = name;
// Create the thread, passing the args pointer from heap
int rc = pthread_create(thread, NULL, &_fun_thread_run, args);
if (0 == rc) {
// We return here, all is well, no stack data leak, args in heap
return thread;
} else {
free(args);
return NULL;
}
}
// ...
// Elsewhere, start some threads!
pthread_t fun_thread1;
pthread_t fun_thread2;
_launch_fun_thread(&fun_thread1, 0xABCDEF12345678ULL, "super FUN thread 1");
usleep(500UL * 1000UL);
_launch_fun_thread(&fun_thread2, 0xDEADBEEF55AA55ULL, "super FUN thread 2");
pthread_join(fun_thread1, NULL);
pthread_join(fun_thread2, NULL);
// ...
Для вашего конкретного примера unsigned long long
вы могли бы просто выделить его вместо структуры:
unsigned long long *thread_arg = calloc(1, sizeof(*thread_arg));
*thread_arg = 123456;
Затем передал это:
pthread_create(thread, NULL, &_fun_thread_run, (void *)thread_arg);
free()
будет сделано в том же месте, и вы можете разыграть от void *
до unsigned long long *
в вашем обработчике потоков.
См. https://gist.github.com/tcarmelveilleux/967728df33215d66e2e126637270901c для полного примера для компиляции одного файла.