通过引用将无符号Long Long传递给pthread_create

时间:2018-05-04 17:13:53

标签: c casting type-conversion pthreads

如果我想将无符号long long传递给pthread_create函数调用,我该怎么做?我理解由于pthread_create具有void *作为最后一个参数意味着存在类型安全问题的机会。

我已经看到它用整数做了这样的事情:

new

然后在线程执行的函数中取消引用int。如果“i”是一个无符号的long long类型,那么同样的工作吗?基本上我想要做的是使用gettid()在unsigned long long变量中获取线程的线程id。谢谢你的帮助!

1 个答案:

答案 0 :(得分:0)

有时,概括问题有助于查看解决方案。将int转换为void *是尝试避免内存分配的一个老技巧。有时您只想配置将运行的线程不仅仅是一个int。

我用来配置pthread的一个常用方法是calloc某个结构,甚至单个值的空间(例如unsigned long long),将它传递给pthread arg并在我的文件中使用它主线程逻辑的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