c - 在 C 中将 "thread entry point"函数调用为 "normal"函数是一种错误的代码实践吗?

标签 c multithreading function pthreads

我最近遇到了一个非常特殊的情况,在这种情况下,我不得不考虑在 C 中使用 POSIX 线程在“正常”函数调用和“线程入口点”函数中使用相同的函数。

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

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

由于“通用”操作集在这两种情况下非常相似,所以我实际上编写了如下代码:

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

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

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

最佳答案

像调用任何其他函数一样调用“线程函数”当然是有效的。只要将(转换)为正确的类型,就没有问题,应该没问题。 这是否是一个好的做法是主观的。这是一种非常罕见的情况,以至于很难找到任何人直截了本地称其为“一种不好的做法,你必须避免”:)

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

/* 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,对于任何多线程程序,您应该考虑的因素都是一样的:函数保持线程安全,并且您从线程函数调用的任何函数也是线程安全的,等等。否则,没有什么可担心的。

关于c - 在 C 中将 "thread entry point"函数调用为 "normal"函数是一种错误的代码实践吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54371413/

相关文章:

c++ - OpenCV:C++ 和 C 性能比较

c - 获取字符数组中初始值的长度

c++ - 从 if 语句中初始化 C++11 线程

java - 如果使用 java.util.concurrent 数据结构,是否需要使用 "synchronized"关键字来获取/添加?

c - 为什么第一个 gets() 函数不起作用?

c - popen 不会捕获命令的所有输出

c - Newlib 在 ARM 嵌入式系统中首次调用时无法分配堆

c - 如何查询多个 pthread(子线程)以了解哪一个线程终止

c++ - std::bind 绑定(bind)函数

c - 使用 typedef 通过引用传递参数