如何使用C中的pthreads时避免code膨胀? [英] How to avoid code bloat when using pthreads in C?

查看:111
本文介绍了如何使用C中的pthreads时避免code膨胀?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

当用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() operator

There 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆