多线程编程之pthread_create pthread_join pthread_attr_t

多线程编程之pthread_create函数应用

pthread_create函数

函数简介

pthread_createUNIX环境创建线程函数

头文件

#include

函数声明

int  pthread_create(pthread_t  *thread,  pthread_attr_t  *attr,  void* (*start_routine)(void  *),  void  *arg);

返回值

若成功则返回0,否则返回出错编号

参数

第一个参数为指向线程标识符的指针。

第二个参数用来设置线程属性。

第三个参数是线程运行函数的起始地址。

最后一个参数是运行函数的参数。

另外

pthread库不是Linux系统默认的库,连接时需要使用静态库libpthread.a,所以在线程函数在编译时,需要连接库函数

 

pthread_join函数

函数简介

函数pthread_join用来等待一个线程的结束。

函数原型为:

int pthread_join(pthread_t thread, void **value_ptr);

参数:

第一个参数为被等待的线程标识符,第二个参数为一个用户定义的指针,它可以用来存储被等待线程的返回值。这个函数是一个线程阻塞的函数,调用它的函数将一直等待到被等待的线程结束为止,当函数返回时,被等待线程的资源被收回。如果执行成功,将返回0,如果失败则返回一个错误号。

举例:

  1. /*thread.c*/  
  2. #include   
  3. #include   
  4.    
  5. /*线程一*/  
  6. void thread_1(void)  
  7. {  
  8.     int i=0;  
  9.     for(i=0;i<=6;i++)  
  10.     {  
  11.         printf("This is a pthread_1.\n");  
  12.         if(i==2)  
  13.             pthread_exit(0);  
  14.         sleep(1);  
  15.     }  
  16. }  
  17.    
  18. /*线程二*/  
  19. void thread_2(void)  
  20. {  
  21.     int i;  
  22.     for(i=0;i<3;i++)  
  23.         printf("This is a pthread_2.\n");  
  24.     pthread_exit(0);  
  25. }  
  26.    
  27. int main(void)  
  28. {  
  29.     pthread_t id_1,id_2;  
  30.     int i,ret;  
  31. /*创建线程一*/  
  32.     ret=pthread_create(&id_1,NULL,(void  *) thread_1,NULL);  
  33.     if(ret!=0)  
  34.     {  
  35.         printf("Create pthread error!\n");  
  36.     return -1;  
  37.     }  
  38. /*创建线程二*/  
  39.      ret=pthread_create(&id_2,NULL,(void  *) thread_2,NULL);  
  40.     if(ret!=0)  
  41.     {  
  42.         printf("Create pthread error!\n");  
  43.     return -1;  
  44.     }  
  45. /*等待线程结束*/  
  46.     pthread_join(id_1,NULL);  
  47.     pthread_join(id_2,NULL);  
  48.     return 0;  
  49. }  

        以下是程序运行结果:

    多线程编程之pthread_create pthread_join pthread_attr_t_第1张图片

         备注:pthread库不是Linux系统默认的库,连接时需要使用静态库libpthread.a,所以在线程函数在编译时,需要连接库函数,如上图    gcc pthread_create.c -o pthread_create -lpthread

     

     

     

    线程属性

           线程具有属性,用pthread_attr_t表示,在对该结构进行处理之前必须进行初始化,在使用后需要对其去除初始化。我们用pthread_attr_init函数对其初始化,用pthread_attr_destroy对其去除初始化。

      

    1

    名称:

    pthread_attr_init/pthread_attr_destroy

    功能:

    对线程属性初始化/去除初始化

    头文件:

    #include

    函数原形:

    int pthread_attr_init(pthread_attr_t*attr);

    int pthread_attr_destroy(pthread_attr_t*attr);

    参数:

    Attr   线程属性变量

    返回值:

    若成功返回0,若失败返回-1

           

      

      

      

      

     

     

     

     

    调用pthread_attr_init之后,pthread_t结构所包含的内容就是操作系统实现支持的线程所有属性的默认值。

           如果要去除对pthread_attr_t结构的初始化,可以调用pthread_attr_destroy函数。如果pthread_attr_init实现时为属性对象分配了动态内存空间,pthread_attr_destroy还会用无效的值初始化属性对象,因此如果经pthread_attr_destroy去除初始化之后的pthread_attr_t结构被pthread_create函数调用,将会导致其返回错误。

      

    线程属性结构如下:

    typedef struct

    {

           int                               detachstate;   线程的分离状态

           int                               schedpolicy;  线程调度策略

           structsched_param              schedparam;  线程的调度参数

           int                               inheritsched;  线程的继承性

           int                                scope;       线程的作用域

           size_t                           guardsize;   线程栈末尾的警戒缓冲区大小

           int                                stackaddr_set;

           void*                          stackaddr;   线程栈的位置

           size_t                           stacksize;    线程栈的大小

    }pthread_attr_t;

      

    每个个属性都对应一些函数对其查看或修改。下面我们分别介绍。

      

    大致步骤为:

    pthread_attr_t attr;

    pthread_attr_init(&attr);

    pthread_attr_setXXX(&attr, 目标值);

    ……//创建线程,其他代码

    pthread_attr_destroy(&attr);

      

    通过一系列的set函数设置pthread_attr_t类型结构体attr的值。

    1.线程分离状态

    int pthread_attr_getdetachstate(const pthread_attr_t *attr, int*detachstate);

    int pthread_attr_setdetachstate(pthread_attr_t *attr, intdetachstate);

    设置线程的分离状态为PTHREAD_CREATE_JOINABLEPTHREAD_CREATE_DETACHED

    默认是joinable,有一些资源会在线程结束后仍然保持占用状态,直到另外的线程对这个线程使用pthread_joindetached线程不是这样子的,它没有被其他的线程所等待(join),自己运行结束了,线程也就终止了,马上释放系统资源。

    若成功返回0,若失败返回-1

      

    2.线程的调度策略

    int pthread_attr_getschedpolicy(const pthread_attr_t *restrict attr,

                  int *restrict policy);

    int pthread_attr_setschedpolicy(pthread_attr_t *attr, int policy);

    设置调度策略为SCHED_OTHERSCHED_FIFOSCHED_RR。默认调度为other

    若成功返回0,若失败返回-1

      

    3.线程的调度参数

    int pthread_attr_getschedparam(const pthread_attr_t *restrict attr,

                                  struct sched_param *restrictparam);

    int pthread_attr_setschedparam(pthread_attr_t *restrict attr,

                  const struct sched_param*restrict param);

    结构param的子成员__sched_priority控制一个优先权值,大的优先权值对应高的优先权。

    若成功返回0,若失败返回-1

      

    4.线程的继承调度

    int pthread_attr_getinheritsched(constpthread_attr_t *restrict attr,

                                     int*restrict inheritsched);

    int pthread_attr_setinheritsched(pthread_attr_t*attr, int inheritsched);

    设置线程是否继承父线程的调度,即此线程的调度策略及优先级是继承于父线程,还是通过set设定两个属性。值为:PTHREAD_INHERIT_SCHEDPTHREAD_EXPLICIT_SCHED

    默认是inherit继承父线程的。

    若成功返回0,若失败返回-1

      

    5.线程的竞争范围

    int pthread_attr_getscope(const pthread_attr_t *restrict attr,

    int *restrict contentionscope);

    int pthread_attr_setscope(pthread_attr_t *attr, int contentionscope);

    定义创建的线程的竞争范围为PTHREAD_SCOPE_SYSTEMPTHREAD_SCOPE_PROCESS

    Linux Threads只实现了PTHREAD_SCOPE_SYSTEM,这意味着,它将和机器上运行的所有进程竞争CPU时间。

    标准指定的另外一个值,PTHREAD_SCOPE_PROCESS,表示竞争只存在于运行中的进程的线程之间:即,线程的优先级是相对于其它进程中的线程的优先级的,而不必考虑进程的优先级如何。LinuxThread不支持PTHREAD_SCOPE_PROCESS

    若成功返回0,若失败返回-1

      

    6.线程的栈的地址和大小

    (1)

    int pthread_attr_getstack(pthread_attr_t *attr,void **stackaddr,size_t*stacksize);

    int pthread_attr_setstack(pthread_attr_t *attr, void *stackaddr,size_t stacksize);

    设置线程栈的起始地址和栈大小。默认起始地址0,大小0x8000008M,我的机子……)。

    PS:使用get时往往显示的是addr = 0size = 0,这可能是系统的BUGsize应给为8M而不是0

    (2)

    上面的2个函数可以细化成4个:

    int pthread_attr_setstackaddr(pthread_attr_t *attr, void *stackaddr);

    int pthread_attr_getstackaddr(pthread_attr_t *attr, void**stackaddr);

    int pthread_attr_setstacksize(pthread_attr_t *attr, size_tstacksize);

    int pthread_attr_getstacksize(pthread_attr_t *attr, size_t*stacksize);

    这里get得到的size8M,所以pthread_attr_getstack获得的size大小是不能说明栈的大小的。

      

    7.栈溢出保护区大小

    intpthread_attr_setguardsize(pthread_attr_t *attr, size_t guardsize);

    intpthread_attr_getguardsize(pthread_attr_t *attr, size_t *guardsize);

    设置线程的栈溢出保护区大小,默认4096B,即4K

      

    8. 设置/获取线程属性对象里CPU 姻亲属性

    int pthread_attr_setaffinity_np(pthread_attr_t *attr,size_tcpusetsize,

    const cpu_set_t *cpuset);

    int pthread_attr_getaffinity_np(pthread_attr_t *attr, size_tcpusetsize,

    cpu_set_t *cpuset);

    函数把 attr 引用的线程属性对象中的 CPU 姻亲掩码设置为cpuset 指定的值。这个属性决定了使用线程属性对象 attr 创建的线程的 CPU 姻亲掩码。

     

    举例说明:

    1. int anyka_pthread_create(pthread_t *thread_id, anyka_thread_main *func, void *arg, int stack_size, int priority)  
    2. {  
    3.        
    4.     int ret;  
    5.     pthread_attr_t SchedAttr;  
    6.     struct sched_param  SchedParam;  
    7.    
    8. #ifdef _POSIX_THREAD_PRIORITY_SCHEDULING  
    9.     //anyka_print("pthread priority(SCHED_RR)=(min=%d,max=%d)\n", sched_get_priority_min(SCHED_RR), sched_get_priority_max(SCHED_RR));  
    10.     //anyka_print("pthread priority(SCHED_FIFO)=(min=%d,max=%d)\n", sched_get_priority_min(SCHED_FIFO), sched_get_priority_max(SCHED_FIFO));  
    11. #endif  
    12.     /** init sched param attribute **/  
    13.     pthread_attr_init(&SchedAttr);  
    14.            
    15.     if(priority != -1)  
    16.     {  
    17.         ret = pthread_attr_setinheritsched(&SchedAttr, PTHREAD_EXPLICIT_SCHED);  
    18.         if (ret != 0)  
    19.              anyka_print("pthread_attr_setschedpolicy, %s\n", strerror(ret));         
    20.         ret = pthread_attr_setschedpolicy(&SchedAttr, SCHED_RR);  
    21.         if (ret != 0)  
    22.             anyka_print("pthread_attr_setschedpolicy, %s\n", strerror(ret));  
    23.         SchedParam.sched_priority = priority;     
    24.         ret = pthread_attr_setschedparam(&SchedAttr, &SchedParam);  
    25.         if (ret != 0)  
    26.             anyka_print("pthread_attr_setschedparam, %s\n", strerror(ret));  
    27.     }  
    28.        
    29.     ret = pthread_attr_setstacksize(&SchedAttr, stack_size);  
    30.     if (ret != 0)  
    31.         anyka_print("pthread_attr_setstacksize, %s\n", strerror(ret));  
    32.     ret = pthread_create(thread_id, &SchedAttr, func, arg);  
    33.     if(ret != 0)  
    34.         anyka_print("pthread_create [ %x ] failed, %s\n", (unsigned int)*func, strerror(ret));  
    35.    
    36.     pthread_attr_destroy(&SchedAttr);  
    37.    
    38.     return ret;  
    39.        
    40. }  

     

     

    #include

    #include

    #include

    void *child_thread(void *arg)

    {

    int policy = 0;

    int max_priority = 0,min_priority = 0;

    struct sched_param param;

    pthread_attr_t attr;

     

    pthread_attr_init(&attr);

    pthread_attr_setinheritsched(&attr,PTHREAD_EXPLICIT_SCHED);

    pthread_attr_getinheritsched(&attr,&policy);

    if(policy == PTHREAD_EXPLICIT_SCHED){

    printf("Inheritsched:PTHREAD_EXPLICIT_SCHED\n");

    }

    if(policy == PTHREAD_INHERIT_SCHED){

    printf("Inheritsched:PTHREAD_INHERIT_SCHED\n");

    }

     

    pthread_attr_setschedpolicy(&attr,SCHED_RR);

    pthread_attr_getschedpolicy(&attr,&policy);

    if(policy == SCHED_FIFO){

    printf("Schedpolicy:SCHED_FIFO\n");

    }

    if(policy == SCHED_RR){

    printf("Schedpolicy:SCHED_RR\n");

    }

    if(policy == SCHED_OTHER){

    printf("Schedpolicy:SCHED_OTHER\n");

    }

    max_priority = sched_get_priority_max(policy);

    min_priority = sched_get_priority_min(policy);

    printf("Maxpriority:%u\n",max_priority);

    printf("Minpriority:%u\n",min_priority);

     

    param.sched_priority = max_priority;

    pthread_attr_setschedparam(&attr,¶m);

    printf("sched_priority:%u\n",param.sched_priority);

    pthread_attr_destroy(&attr);

    }

     

    int main(int argc,char *argv[])

    {

    pthread_t child_thread_id;

    pthread_create(&child_thread_id, NULL, child_thread,NULL);

    pthread_join(child_thread_id, NULL);

    }

     

    ==[23]==gaoke@dev64_23:~/code$g++ -o test gaoke.cpp -lpthread
    ==[23]==gaoke@dev64_23:~/code$./test
    Inheritsched:PTHREAD_EXPLICIT_SCHED
    Schedpolicy:SCHED_RR
    Maxpriority:99
    Minpriority:1
    sched_priority:99

你可能感兴趣的:(计算机语言与算法)