免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 1110 | 回复: 0
打印 上一主题 下一主题

linux多线程基础(一) [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2006-09-08 10:56 |只看该作者 |倒序浏览

线程创建
#include
int pthread_create(pthread_t *thread,
                     const pthread_attr_t * attr,
                     void *(*start_routine)(void *), void *arg);
参数:
Ø         Thread为创建的线程ID
Ø         Attr为创建线程时设置的线程属性(见下文)
Ø         start_routine为创建的线程所执行的函数。该函数可以返回void*类型的返回值,由pthread_join()获取。
Ø         arg为创建的线程所执行的函数的参数。可以为任意类型的参数,传入时转换为void*既可,eg: (void*)arg static_cast(arg);
该函数成功返回零,不成功返回一个error code,常见错误如下
EAGAIN
system did not have the resources to create the thread, or would exceed system limit on total number of threads in a process
EINVAL
attr parameter is invalid
EPERM
caller does not have the appropriate permissions to set scheduling policy or parameters specified by attr
线程属性
pthread_create()中的attr参数是一个结构指针,结构中的元素分别对应着新线程的运行属性。如果创建线程时使用该参数,则必须先初始化该参数pthread_attr_init(&attr);
然后再设置参数中各元素。该结构中定义在/usr/include/bits/ pthreadtypes.h中:
/* Attributes for threads. */
typedef struct __pthread_attr_s
{
int      __detachstate;
int       __schedpolicy;
struct    __sched_param __schedparam;
int       __inheritsched;
int       __scope;
size_t    __guardsize;
int       __stackaddr_set;
void      *__stackaddr;
size_t    __stacksize;
} pthread_attr_t;
其中各元素含义:
Ø         __detachstate,表示新线程是否与进程中其他线程脱离同步,如果置位则新线程不能用pthread_join()来同步,且在退出时自行释放所占用的资源。缺省为PTHREAD_CREATE_JOINABLE状态。这个属性也可以在线程创建并运行以后用pthread_detach()来设置,而一旦设置为PTHREAD_CREATE_DETACH状态(不论是创建时设置还是运行时设置)则不能再恢复到PTHREAD_CREATE_JOINABLE状态。该参数涉及函数:
int pthread_attr_setdetachstate (pthread_attr_t *__attr,
int __detachstate);
int pthread_attr_getdetachstate (__const pthread_attr_t *__attr,
                    int *__detachstate);
        __detachstate可取值:PTHREAD_CREATE_JOINABLE, PTHREAD_CREATE_DETACH。
Ø         __schedpolicy,表示新线程的调度策略,主要包括SCHED_OTHER(正常、非实时)、SCHED_RR(实时、轮转法)和SCHED_FIFO(实时、先入先出)三种,缺省为SCHED_OTHER,后两种调度策略仅对超级用户有效。运行时可以用过pthread_setschedparam()来改变。该参数涉及函数:
int pthread_attr_setschedpolicy (pthread_attr_t *__attr, int __policy);
int pthread_attr_getschedpolicy (__const pthread_attr_t *__restrict
                                __attr, int *__restrict __policy);
Ø         __schedparam,一个struct sched_param结构,其中有一个sched_priority整型变量表示线程的运行优先级。这个参数仅当调度策略为实时(即SCHED_RR或SCHED_FIFO)时才有效,并可以在运行时通过pthread_setschedparam()函数来改变,缺省为0。该参数涉及函数:
nt pthread_attr_setschedparam (pthread_attr_t *__restrict __attr,
                                __const struct sched_param *__restrict  __param);
int pthread_attr_getschedparam (__const pthread_attr_t *__restrict  __attr,
                                struct sched_param *__restrict __param);
Ø         __inheritsched,有两种值可供选择:PTHREAD_EXPLICIT_SCHED和PTHREAD_INHERIT_SCHED,前者表示新线程使用显式指定调度策略和调度参数(即attr中的值),而后者表示继承调用者线程的值。缺省为PTHREAD_EXPLICIT_SCHED。
int pthread_attr_setinheritsched (pthread_attr_t *__attr,
                     int __inherit);
int pthread_attr_getinheritsched (__const pthread_attr_t *__restrict
                     __attr, int *__restrict __inherit);
Ø         __scope,表示线程间竞争CPU的范围,也就是说线程优先级的有效范围。POSIX的标准中定义了两个值:PTHREAD_SCOPE_SYSTEM和PTHREAD_SCOPE_PROCESS,前者表示与系统中所有线程一起竞争CPU时间,后者表示仅与同进程中的线程竞争CPU。该参数涉及函数:
int pthread_attr_setscope (pthread_attr_t *__attr, int __scope);
int pthread_attr_getscope (__const pthread_attr_t *__restrict __attr,
                             int *__restrict __scope);
pthread_attr_t结构中还有一些值,但不使用pthread_create()来设置。
另外还有pthread_attr_destroy(pthread_attr_t *attr),该函数使线程属性无效。

线程取消
线程取消一般分为两种情况,一种是线程主体函数退出时自动取消或者调用pthread_exit()退出,另一种是接收到终止请求而退出。
    当线程接收到cancel信号时,有不同的处理方法,或者忽略、或者立即终止、或者继续运行至Cancelation-point(取消点),由不同的Cancelation状态决定。缺省处理是执行到取消点退出。
    取消点: pthread_join()、pthread_testcancel()、pthread_cond_wait()、pthread_cond_timedwait()、sem_wait()、sigwait()等函数以及read()、write()等会引起阻塞的系统调用都是取消点(Cancelation-point)。由于C库函数都不是取消点,所以可以在需要作为取消点的系统调用前后均调用pthread_testcancel。
    涉及的几个函数:
Ø         int pthread_cancel(pthread_t thread)
发送终止信号给thread线程,如果成功则返回0,否则为非0值。发送成功并不意味着thread会终止。
Ø         int pthread_setcancelstate(int state, int *oldstate)
设置本线程对Cancel信号的反应,state有两种值:PTHREAD_CANCEL_ENABLE(缺省)和PTHREAD_CANCEL_DISABLE,分别表示收到信号后设为CANCLED状态和忽略CANCEL信号继续运行;old_state如果不为NULL则存入原来的Cancel状态以便恢复。
Ø         int pthread_setcanceltype(int type, int *oldtype)
设置本线程取消动作的执行时机,type由两种取值:PTHREAD_CANCEL_DEFFERED和PTHREAD_CANCEL_ASYCHRONOUS,仅当Cancel状态为Enable时有效,分别表示收到信号后继续运行至下一个取消点再退出和立即执行取消动作(退出);oldtype如果不为NULL则存入运来的取消动作类型值。
Ø         void pthread_testcancel(void)
检查本线程是否处于Canceld状态,如果是,则进行取消动作,否则直接返回。

当线程属性__detachstate设置为PTHREAD_CREATE_JOINABLE时,可以在主线程调用pthread_join()来进行等待(同步)。
函数原型:
    int pthread_join (pthread_t __th, void **__thread_return);
__th为需要等待的线程ID,第二个参数为该线程的返回值。需要注意的是一个线程仅允许唯一的一个线程使用pthread_join()等待它的终止,并且被等待的线程应该处于可join状态,即非DETACHED状态。如果进程中的某个线程执行了pthread_detach(th),则th线程将处于DETACHED状态,这使得th线程在结束运行时自行释放所占用的内存资源,同时也无法由pthread_join()同步,pthread_detach()执行之后,对th请求pthread_join()将返回错误。
一个可join的线程所占用的内存仅当有线程对其执行了pthread_join()后才会释放,因此为了避免内存泄漏,所有线程的终止,要么已设为DETACHED,要么就需要使用pthread_join()来回收。
    建议在函数结束时调用pthread_exit(),不采用return 。



线程私有数据
    多线程中,由于数据空间共享,所以全局数据和静态数据也是共享的,如果各线程中需要自己线程内的“全局变量”则需要用到线程私有数据(Thread-specific Data,或TSD)。线程私有数据采用同名而不同地址的方法实现。一般是函数内存放在堆栈中的数据。
涉及相关函数:
Ø         int pthread_key_create (pthread_key_t *__key,
                   void (*__destr_function) (void *));
    该函数创建一个私有数据key。其中第二个参数为清理函数,即该key释放时调用该函数用来清理。
Ø         int pthread_key_delete (pthread_key_t __key);
该函数用来释放创建的key
Ø         int pthread_setspecific (pthread_key_t __key,
                __const void *__pointer);
    该函数用来将__printer的值与__key相连。
Ø         void *pthread_getspecific (pthread_key_t __key);
该函数用来读取和 __key相关联的数据。
一般使用情况:
全局变量中声明pthread_key_t __key,主线程中创建该key,然后该key分别与各线程中的私有数据关联,一般是指函数内存放在堆栈中的数据。其他函数调用pthread_getspecific函数可取得该key关联的数据,以实现全局变量的功能。


本文来自ChinaUnix博客,如果查看原文请点:http://blog.chinaunix.net/u/1889/showart_166918.html
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP