我最近遇到了一个非常特殊的情况,在这种情况下,我不得不考虑在 C 中使用 POSIX 线程在“正常”函数调用和“线程入口点”函数中使用相同的函数。
让我更好地解释一下情况:我有一个程序,根据用户的选择,它应该执行不同的任务。
两个任务非常相似,但它们的区别在于,在一种情况下,一组操作应该与另一组操作并行执行,而在第二种情况下,几乎相同的一组操作应该是必然的在另一个之前执行,无需创建专用线程。
由于“通用”操作集在这两种情况下非常相似,所以我实际上编写了如下代码:
if(task_type==0) {
// Create two threads
pthread_create(&tid[0],NULL,&common_operations,(void *) &args);
pthread_create(&tid[1],NULL,¶llel_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/