如何使用C中的pthreads时避免code膨胀? [英] How to avoid code bloat when using pthreads in C?
问题描述
当用C编写线程code,我首先要创造一些结构
,其中包括所有的参数和一个包装函数。这导致了大量的code膨胀的并且不容易阅读。参见:
结构some_function_args {
INT ARG1;
INT ARG2;
INT ARG3;
};无效some_function_wrapper(结构some_function_args *参数){
some_function(args-> ARG1,args-> ARG2,args-> ARG3);
}诠释主(){
结构my_args;
my_args.arg1 = 1;
my_args.arg2 = 2;
my_args.arg3 = 3; 在pthread_create(...,some_function_wrapper,&安培; my_args);
在pthread_join(...);
}
是否有某种宏或库(可能使用可变参数
),它会自动创建为我所需要的结构和包装函数,这样吗?或者,这根本不可能用C?
INT的main(){
MY_THREAD线程= {IN_THREAD
some_function(1,2,3);
} JOIN_THREAD(螺纹);
}
编辑:我发布了一些code。请参见 threadify.h 。
块引用>通过下面的宏,你可以做这样的事情:
的char a ='A';
INT B = 23;
的char [] C =示例;
线程的pthread_t;// THREAD3因为它需要的变量类型的3个参数。
THREAD3(线程,A,B,C,{
的printf(测试:%C%d个%S \\ n,A,B,C);
});JOIN(螺纹);这是在GCC可能的,因为GCC有两个非标准扩展:
- 嵌套函数
- 的
typeof运算()
运营商有在这个巨大的宏混乱一些缺点:
- 您无法通过右值(因为它无法创建指向他们)
您需要使用
THREAD0
,线程1
,...取决于宏观上的适当数量参数(不知道是否有可能解决这个使用复杂的宏)的#include<&stdio.h中GT;
#包括LT&;&pthreads.h中GT;//嵌套定义来解决preprocessor preSCAN
#定义__CAT(ARG1,ARG2)ARG1 ARG2 ##
CAT的#define(ARG1,ARG2)__CAT(ARG1,ARG2)//使用当前行号来创建对象的唯一名称
的#define NAME(ARG1)CAT(ARG1,__LINE__)//创建不带任何参数线程
#定义THREAD0(螺纹,code)\\
无效名称(__ pthread_wrapper)(无效){\\
做{code;}而(0); \\
}; \\
在pthread_create(安培;螺纹,NULL,(无效*)名称(__ pthread_wrapper),NULL);//创建一个结构创建具有一个参数一个线程
//并通过这个结构传递的所有值。
#定义线程1(线程,ARG1,code)\\
typedef结构{\\
typeof运算(ARG1)*姓名(__ pthread_arg1); \\
} NAME(__ pthread_struct); \\
无效名称(__ pthread_wrapper)(NAME(__ pthread_struct)*数据){\\
做{code;}而(0); \\
}; \\
NAME(__ pthread_struct)名称(__数据); \\
NAME(__数据).NAME(__ pthread_arg1)=安培; ARG1; \\
在pthread_create(安培;螺纹,NULL,(无效*)名称(__ pthread_wrapper),放大器; NAME(__数据));#定义线程2(线程,ARG1,ARG2,code)\\
typedef结构{\\
typeof运算(ARG1)*姓名(__ pthread_arg1); \\
typeof运算(ARG2)*姓名(__ pthread_arg2); \\
} NAME(__ pthread_struct); \\
无效名称(__ pthread_wrapper)(NAME(__ pthread_struct)*数据){\\
做{code;}而(0); \\
}; \\
NAME(__ pthread_struct)名称(__数据); \\
NAME(__数据).NAME(__ pthread_arg1)=安培; ARG1; \\
NAME(__数据).NAME(__ pthread_arg2)=安培; ARG2; \\
在pthread_create(安培;螺纹,NULL,(无效*)名称(__ pthread_wrapper),放大器; NAME(__数据));#定义THREAD3(螺纹,ARG1,ARG2,ARG3,code)\\
typedef结构{\\
typeof运算(ARG1)*姓名(__ pthread_arg1); \\
typeof运算(ARG2)*姓名(__ pthread_arg2); \\
typeof运算(参数3)*姓名(__ pthread_arg3); \\
} NAME(__ pthread_struct); \\
无效名称(__ pthread_wrapper)(NAME(__ pthread_struct)*数据){\\
做{code;}而(0); \\
}; \\
NAME(__ pthread_struct)名称(__数据); \\
NAME(__数据).NAME(__ pthread_arg1)=安培; ARG1; \\
NAME(__数据).NAME(__ pthread_arg2)=安培; ARG2; \\
NAME(__数据).NAME(__ pthread_arg3)=安培; ARG3; \\
在pthread_create(安培;螺纹,NULL,(无效*)名称(__ pthread_wrapper),放大器; NAME(__数据));/ * THREAD4,THREAD5,... * /#定义JOIN(线程),在pthread_join(线程,NULL);
When writing threaded code in C, I first have to create some
struct
which includes all the arguments and a wrapper function. This leads to lots of code bloat and is not easy to read. See:struct some_function_args { int arg1; int arg2; int arg3; }; void some_function_wrapper(struct some_function_args* args) { some_function(args->arg1, args->arg2, args->arg3); } int main() { struct my_args; my_args.arg1 = 1; my_args.arg2 = 2; my_args.arg3 = 3; pthread_create(..., some_function_wrapper, &my_args); pthread_join(...); }
Is there some kind of macro or library (maybe using
varargs
) which automatically creates the needed structs and wrapper functions for me, like this? Or is this not possible at all in C?int main() { MY_THREAD thread = IN_THREAD { some_function(1, 2, 3); } JOIN_THREAD(thread); }
解决方案EDIT: I released some code. See threadify.h.
With the following macros you can do things like this:
char a = 'A'; int b = 23; char[] c = "Example"; pthread_t thread; // THREAD3 because it takes 3 arguments of variable type. THREAD3(thread, a, b, c, { printf("test: %c %d %s\n", a, b, c); }); JOIN(thread);
It's possible in GCC, because GCC has two non-standard extensions:
- nested functions
- The
typeof()
operatorThere are some drawbacks in this huge mess of macros:
- You cannot pass rvalues (because it's not possible to create pointers to them)
You need to use the appropriate
THREAD0
,THREAD1
, ... macro depending on the number of arguments (not sure if it's possible to work around this using variadic macros).#include <stdio.h> #include <pthread.h> // Nested definition to work around preprocessor prescan #define __CAT(arg1, arg2) arg1 ## arg2 #define CAT(arg1, arg2) __CAT(arg1, arg2) // Use the current line number to create a unique name for objects #define NAME(arg1) CAT(arg1, __LINE__) // Creates a thread without any arguments #define THREAD0(thread, code) \ void NAME(__pthread_wrapper)(void) {\ do {code;} while(0); \ }; \ pthread_create(&thread, NULL, (void*)NAME(__pthread_wrapper), NULL); // Creates a thread with one argument by creating a struct // and passing all values via this struct. #define THREAD1(thread, arg1, code) \ typedef struct { \ typeof(arg1)* NAME(__pthread_arg1); \ } NAME(__pthread_struct); \ void NAME(__pthread_wrapper)(NAME(__pthread_struct)* data) {\ do {code;} while(0); \ }; \ NAME(__pthread_struct) NAME(__data); \ NAME(__data).NAME(__pthread_arg1) = &arg1; \ pthread_create(&thread, NULL, (void*)NAME(__pthread_wrapper), &NAME(__data)); #define THREAD2(thread, arg1, arg2, code) \ typedef struct { \ typeof(arg1)* NAME(__pthread_arg1); \ typeof(arg2)* NAME(__pthread_arg2); \ } NAME(__pthread_struct); \ void NAME(__pthread_wrapper)(NAME(__pthread_struct)* data) {\ do {code;} while(0); \ }; \ NAME(__pthread_struct) NAME(__data); \ NAME(__data).NAME(__pthread_arg1) = &arg1; \ NAME(__data).NAME(__pthread_arg2) = &arg2; \ pthread_create(&thread, NULL, (void*)NAME(__pthread_wrapper), &NAME(__data)); #define THREAD3(thread, arg1, arg2, arg3, code) \ typedef struct { \ typeof(arg1)* NAME(__pthread_arg1); \ typeof(arg2)* NAME(__pthread_arg2); \ typeof(arg3)* NAME(__pthread_arg3); \ } NAME(__pthread_struct); \ void NAME(__pthread_wrapper)(NAME(__pthread_struct)* data) {\ do {code;} while(0); \ }; \ NAME(__pthread_struct) NAME(__data); \ NAME(__data).NAME(__pthread_arg1) = &arg1; \ NAME(__data).NAME(__pthread_arg2) = &arg2; \ NAME(__data).NAME(__pthread_arg3) = &arg3; \ pthread_create(&thread, NULL, (void*)NAME(__pthread_wrapper), &NAME(__data)); /* THREAD4, THREAD5, ... */ #define JOIN(thread) pthread_join(thread, NULL);
这篇关于如何使用C中的pthreads时避免code膨胀?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!