在 C 中调用 "thread entry point" 函数作为 "normal" 函数是一种糟糕的代码习惯吗?

Is calling a "thread entry point" function, in C, as "normal" function, a bad code practice?

我最近遇到了一个非常特殊的情况,我不得不考虑在 "normal" 函数调用和 "thread entry point" 函数中使用相同的函数,使用 POSIX 线程, 在 C.

让我更好地解释一下情况:我有一个程序,根据用户的选择,它应该执行不同的任务。

两项任务非常相似,但它们的不同之处在于,在一种情况下,一组操作应与另一组操作并行执行,而在第二种情况下,几乎相同的一组操作应该必须在另一个之前执行,无需创建专用线程。

由于"common"组操作在这两种情况下非常相似,所以我实际上写了如下代码:

if(task_type==0) {
    // Create two threads
    pthread_create(&tid[0],NULL,&common_operations,(void *) &args);
    pthread_create(&tid[1],NULL,&parallel_operations,(void *) &args);

    pthread_join(tid[0],NULL);
    pthread_join(tid[1],NULL);
} else if(task_type==1) {
    common_operations(&args); // Thread entry point function called as "normal function"
    sequential_operations(&args); // Different with respect to "parallel_operations"
}

将 "common_operations" 函数定义为:

static void *common_operations (void *arg) {
    // Properly casting void *arg to the right struct, containing, among the other things, "task_type"      

    // Function body....

    if(arg->task_type==0) {
        pthread_exit(NULL);
    } else {
        return NULL;
    }
}

我从未见过以这种方式使用的线程入口点函数,我想知道这是否可以被认为是可以接受的,或者以这种方式混合使用是否是一种糟糕的代码实践。

此外,对于这个具体案例有更好的解决方案吗?

像调用任何其他函数一样调用 "thread function" 当然是有效的。只要将(转换)为正确的类型,就没有问题,应该没问题。 它是否是好的做法是主观的。这是一个非常罕见的,很难找到任何人直接称呼它 "a bad practice, you must avoid" :)

但是,您可以稍微重写,以便 "normal" 函数与线程函数的区别很清楚。并使其成为 void 函数,这样它就不会 return 单线程调用中的任何东西,否则看起来有点奇怪。这也可以避免潜在的意大利面条代码。

/* Use it in direct, single-threaded call */
static void common_operations(common_arg_type *arg) {
    // Function body....
}

/* Use it in pthread_create call */
static void *common_operations_thread(void *arg) {
    common_operations(args);
    return NULL; /* equivalent to pthread_exit(NULL); */
}

IMO,对于任何多线程程序,您应该考虑的因素都是一样的:函数保持线程安全,并且您从线程函数调用的任何函数也是线程安全的,等等。否则就没什么好担心的了。