ImageVerifierCode 换一换
格式:DOCX , 页数:111 ,大小:261.15KB ,
资源ID:17982113      下载积分:3 金币
快捷下载
登录下载
邮箱/手机:
温馨提示:
快捷下载时,用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)。 如填写123,账号就是123,密码也是123。
特别说明:
请自助下载,系统不会自动发送文件的哦; 如果您已付费,想二次下载,请登录后访问:我的下载记录
支付方式: 支付宝    微信支付   
验证码:   换一换

加入VIP,免费下载
 

温馨提示:由于个人手机设置不同,如果发现不能下载,请复制以下地址【https://www.bdocx.com/down/17982113.html】到电脑端继续下载(重复下载不扣费)。

已注册用户请登录:
账号:
密码:
验证码:   换一换
  忘记密码?
三方登录: 微信登录   QQ登录  

下载须知

1: 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。
2: 试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓。
3: 文件的所有权益归上传用户所有。
4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
5. 本站仅提供交流平台,并不能对任何下载内容负责。
6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

版权提示 | 免责声明

本文(多线程程序设计 for LinuxWord文件下载.docx)为本站会员(b****6)主动上传,冰豆网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知冰豆网(发送邮件至service@bdocx.com或直接QQ联系客服),我们立即给予删除!

多线程程序设计 for LinuxWord文件下载.docx

1、数据类型,所以可以移植的操作系统不能把它作为整数处理。因此必须使用函数来对来对两个线程 ID 进行比较。1名称::pthread_equal功能:比较两个线程 ID头文件:#include 函数原形:int pthread_equal(pthread_t tid1,pthread_t tid2);参数:tid1 进程 1idtid2 进程 2id返回值:若相等返回非 0 值,否则返回 02pthread_self获取自身线程的 idpthread_t pthread_self(void);无调用线程的线程 id六 线 程 的 创 建3pthread_create创建线程int pthread_

2、create(pthread_t *restrict tidp,const pthread _attr_t*restrict attr,void *(*start_rtn)(void),void *restrict arg);若成功返回则返回 0,否则返回错误编号当 pthread_creat 成功返回时, tidp 指向的内存单元被设置为新创建线程的线程 ID。attr 参数用于定制各种不同的线程属性。可以把它设置为 NULL,创建默认的 线程属性。新创建的线程从 start_rtn 函数的地址开始运行,该函数只有一个无类型指 针参数 arg,如果需要向 start_rtn 函数传递的参数不

3、止一个,那么需要把这些参数 放到一个结构中,然后把这个结构的地址作为 arg 参数传入。void printids(const char *s)printf(“%s pid:%u tid:%u n“, s,getpid(),pthread_self();void *thr_fn(void *arg)printids(“new thread: “);int main()int err; pthread_t tid; err=pthread_create(&tid,NULL,thr_fn,NULL); if(err=0)printf(“cant create thread:%sn”,strerro

4、r(err);printids(“main thread:sleep(1);exit(0);关于进程的编译我们都要加上参数 lpthread 否则提示找不到函数的错误。具体编译方法是 cc lpthread o gettid gettid.c运行结果为main thread: pid 14954 tid 134529024 new thread: pid 14954 tid 134530048七 .线 程 的 终 止 线程是依进程而存在的,当进程终止时,线程也就终止了。当然也有在不终止整个进程的情况下停止它的控制流。(1)线程只是从启动例程中返回,返回值是线程的退出码。(2)县城可以被同一进程

5、中的其他线程取消。(3)线程调用 pthread_exit.4pthread_exit终止一个线程void pthread_exit(void *rval_ptr);rval_prt 是一个无类型指针,与传给启动例程的单个参数类似。进程中的其他线程可以调用 pthread_join 函数访问到这个指针。pthread_join获得进程的终止状态int pthread_join(pthread_t thread,void *rval_ptr);若成功返回 0,否则返回错误编号。5当一个线程通过调用 pthread_exit 退出或者简单地从启动历程中返回时,进程 中的其他线程可以通过调用 pth

6、read_join 函数获得进程的退出状态。调用 pthread_join 进程将一直阻塞,直到指定的线程调用 pthread_exit,从启动例程中 或者被取消。如果线程只是从它的启动历程返回,rval_ptr 将包含返回码。string.hvoid *thr_fn1(void *arg)printf(“thread 1 returningn”);return(void *)1);void *thr_fn2(void *arg)printf(“thread 2 exitingn”);return(void *)2);pthread_t tid1,tid2;void *tret;pthread

7、_create(&tid1,NULL,thr_fn1,NULL); pthread_create(&tid2,NULL,thr_fn2,NULL); pthread_join(tid1,&tret);printf(“thread 1 exit code %dn”,(int)tret);pthread_join(tid2,&printf(“thread 2 exit code %dn”,(int)tret);运行结果是:thread 1 returning thread 2 exiting thread 1 exit code 1 thread 2 exit code 26pthread_det

8、ach使线程进入分离状态。int pthread_detach(pthread_t tid);若成功则返回 0,否则返回错误编号。在默认情况下,线程的终止状态会保存到对该线程调用 pthread_join,如果线 程已经处于分离状态,线程的底层存储资源可以在线程终止时立即被收回。当线 程被分离时,并不能用 pthread_join 函数等待它的终止状态。对分离状态的线 程进行 pthread_join 的调用会产生失败,返回 EINVAL.pthread_detach 调 用可以用于使线程进入分离状态。7pthread_cancel取消同一进程中的其他线程int pthread_cancel(

9、pthread_t tid);tid 线程 id在默认的情况下,pthread_cancel 函数会使由 tid 标识的线程的行为表现 为如同调用了参数为 PTHEAD_CANCELED 的 pthread_exit 函数,但是,线 程可以选择忽略取消方式和控制取消方式。pthread_cancel 并不等待线程终止, 它仅仅提出请求。pthread_cancel_push/ pthread_cancel_push_pop线程清理处理程序void pthread_cancel_push(void (*rtn)(void *),void*arg);void pthread_cancel_pop(

10、int execute);rtn 处理程序入口地址arg 传递给处理函数的参数8线程可以安排它退出时需要调用的函数,这样的函数称为线程清理处理程序, 线程可以建立多个清理处理程序。处理程序记录在栈中,也就是说它们的执行顺 序与它们注册时的顺序相反。要注意的是如果线程是通过从他的启动例程中返回而终止的,它的处理程 序就不会调用。还要注意清理处理程序是按照与它们安装时相反的顺序调用的。stdio.hvoid cleanup(void *arg)printf(“cleanup: %sn”,(char *)arg);void *thr_fn(void *arg) /*线程入口地址*/printf(“t

11、hread startn”);pthread_cleanup_push(cleanup,”thread first handler”);/*设置第一个线程处理程序*/pthread_cleanup_push(cleanup,”thread second handler”); /*设置第二个线程处理程序*/printf(“thread push completen”); pthread_cleanup_pop(0); /*取消第一个线程处理程序*/ pthread_cleanup_pop(0); /*取消第二个线程处理程序*/pthread_t tid;pthread_creat(&tid,NU

12、LL,thr_fn,(void *)1); /*创建一个线程*/pthread_join(tid,& /*获得线程终止状态*/ptinrf(“thread exit code %dn”,(int)tret);八 、 一 次 性 初 始 化有时候我们需要对一些 posix 变量只进行一次初始化,如线程键(我下面会讲到)。如果我们进行多次初始化程序就会出现错误。在传统的顺序编程中,一次性初始化经常通过使用布尔变量来管理。控制变量被静态初始化为 0,而任何依赖于初始化的代码都能测试该变量。如果变量值仍然为 0,则它能实行初始化,然后将变量置为 1。以后检查的代码将跳过初始化。但是在多线程程序设计中,

13、事情就变的复杂的多。如果多个线程并发地执行初始化序列代码,2 个线程可能发现控制变量为 0,并且都实行初始化,而该过程本该仅仅执行一次。初始化的状态必须由互斥量保护。如果我们需要对一个 posix 变量静态的初始化,可使用的方法是用一个互斥量对该变量的初始话进行控制。但有时候我们需要对该变量进行动态初始化,pthread_once 就会方便的多。9.pthread_once一次性初始化pthread_once_t once_control=PTHREAD_ONCE_INIT;int pthread_once(pthread_once_t*once_control,void(*init_rout

14、ine)(void);once_control 控制变量init_routine 初始化函数若成功返回 0,若失败返回错误编号。类型为 pthread_once_t 的变量是一个控制变量。控制变量必须使用PTHREAD_ONCE_INIT 宏静态地初始化。pthread_once 函数首先检查控制变量,判断是否已经完成初始化,如果完成就简单地返回;否则,pthread_once 调用初始化函数,并且记录下初始化被完成。如果在一个线程初始时,另外的线程调用 pthread_once,则调用线程等待,直到那个现成完成初始话返回。下面就是该函数的程序例子:pthread_once_t once=PT

15、HREAD_ONCE_INIT;pthread_mutex_t mutex;/*互斥量,我们后面会讲到*/void once_init_routine(void)/*一次初始化函数*/int status;status=pthread_mutex_init(&mutex,NULL);/*初始化互斥量*/if(status=0)printf(“Init success!,My id is %u”,pthread_self();void *child_thread(void *arg)printf(“Im child ,My id is %u”,pthread_self();pthread_onc

16、e(&once,once_init_routine); /*子线程调用一次性初始化函数*/int main(int argc,char *argv )pthread_t child_thread_id;child_thread_id,NULL,child_thread,NULL);/*创建 子线程*/printf(“Im father,my id is %u”,pthread_self();/*父线程调用一次性初始化函pthread_join(child_thread_id,NULL);程序运行结果如下:./onceIm father,My id is 3086874304Init succe

17、ss!,My id is 3086874304Im child, My id is 3086871472从上面的结果可以看到当主函数初始化成功后,子函数初始化失败。九 、 线 程 的 私 有 数 据 在进程内的所有线程共享相同的地址空间,任何声明为静态或外部的变量,或在进程堆声明的变量,都可以被进程所有的线程读写。那怎样才能使线程序拥有自己的私有数据呢。posix 提供了一种方法,创建线程键。10.pthread_key_create建立线程私有数据键int pthread_key_create(pthread_key_t*key,void(*destructor)(void *);key 私

18、有数据键destructor 清理函数第一个参数为指向一个键值的指针,第二个参数指明了一个 destructor 函数(清理函数),如果这个参数不为空,那么当每个线程结束时,系统将调用这个函数来释放绑定在这个键上的内存块。这个函数常和函数 pthread_once 一起使用,为了让这个键只被创建一次。函数 pthread_once 声明一个初始化函数,第一次调用 pthread_once 时它执行这个函数,以后的调用将被它忽略。下面是程序例子:pthread_key_t tsd_key;pthread_once_t key_once=PTHREAD_ONCE_INIT;void once_ro

19、utine(void)status=pthread_key_create(&tsd_key,NULL);/*初始化线程私有数据键*/if(status=0)printf(“Key create success! My id is %un”,pthread_self();printf(“Im child,My id is %un”,pthread_self();key_once,once_routine);/* 调用一次性初始化函数*/printf(“Im father,my id is%un”,pthread_self();Im father,My id is 3086231232Key cr

20、eate success! My id is 3086231232Im child,My id is 2086228400第二章 线 程 高 级 知 识一 线 程 属 性线程具有属性,用 pthread_attr_t 表示,在对该结构进行处理之前必须进行初始化,在使用后需要对其去除初始化。我们用 pthread_attr_init 函数对其初始化,用 pthread_attr_destroy 对其去除初始化。pthread_attr_init/pthread_attr_destroy对线程属性初始化/去除初始化int pthread_attr_init(pthread_attr_t *attr

21、);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 去除

22、初始化之后的 pthread_attr_t 结构被 pthread_create 函数调用,将会导致其返回错误。线程属性结构如下:typedef structint detachstate; 线程的分离状态int schedpolicy; 线程调度策略struct sched_param schedparam; 线程的调度参数int inheritsched; 线程的继承性int scope; 线程的作用域size_t guardsize; 线程栈末尾的警戒缓冲区大小int stackaddr_set;void *stackaddr;线程栈的位置size_tstacksize;线程栈的大小pt

23、hread_attr_t;每个个属性都对应一些函数对其查看或修改。下面我们分别介绍。二 、 线 程 的 分 离 状 态线程的分离状态决定一个线程以什么样的方式来终止自己。在默认情况下线程是非分离状态的,这种情况下,原有的线程等待创建的线程结束。只有当pthread_join()函数返回时,创建的线程才算终止,才能释放自己占用的系统资源。而分离线程不是这样子的,它没有被其他的线程所等待,自己运行结束了,线程也就终止了,马上释放系统资源。程序员应该根据自己的需要,选择适当的分离状态。所以如果我们在创建线程时就知道不需要了解线程的终止状态,则可以 pthread_attr_t 结构中的 detachstate 线程属性,让线程以分离状态启动。pthread_attr_getdetachstate/pthread_attr_setdetachstate获取/修改线程的分离状态属性int pthread_attr_getdetachstate(const pthread_attr_t * attr,int*detachstate);int pthread_attr_setdetachstate(pthread_attr_t *attr,int detachstate);

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1