操作系统课件:Linux 多线程技术

上传人:努力****83 文档编号:187568538 上传时间:2023-02-15 格式:PPT 页数:25 大小:1.60MB
收藏 版权申诉 举报 下载
操作系统课件:Linux 多线程技术_第1页
第1页 / 共25页
操作系统课件:Linux 多线程技术_第2页
第2页 / 共25页
操作系统课件:Linux 多线程技术_第3页
第3页 / 共25页
资源描述:

《操作系统课件:Linux 多线程技术》由会员分享,可在线阅读,更多相关《操作系统课件:Linux 多线程技术(25页珍藏版)》请在装配图网上搜索。

1、Linux 多线程技术 POSIX 线程库Pthreads使用fork()创建进程 代价昂贵进程间通信方式较复杂操作系统在实现进程间的切换比线程切换更费时 使用pthreads库创建线程创建进程比创建线程更快线程间的通信方式更容操作系统对线程的切换比对进程的切换更容易和快速 线程的创建#include int pthread_create(pthread_t *thread,pthread_attr_t*attr,void*(*start_routine)(void*),void*arg);第一个参数为指向线程标识符的指针。第二个参数用来设置线程属性。第三个参数是线程运行函数的起始地址。最后一

2、个参数是运行函数的参数。当创建线程成功时,函数返回0,若不为0则说明创建线程失败,常见的错误返回代码为EAGAIN和EINVAL。前者表示系统限制创建新的线程,例如线程数目过多了;后者表示第二个参数代表的线程属性值非法。一个简单例子#include#include#include#include#include#include#include#include#include#includepthread_t ntid;pthread_t ntid;void void*thr_fn(void thr_fn(void*arg)arg)printids(new thread:);printids(n

3、ew thread:);return(void return(void*)0);)0);int main()int main()int err;int err;err=pthread_create(&ntid,NULL,thr_fn,NULL);err=pthread_create(&ntid,NULL,thr_fn,NULL);if(err!=0)if(err!=0)printf(cant create thread:%sn,strerror(err);printf(cant create thread:%sn,strerror(err);return 1;return 1;sleep(1)

4、;sleep(1);return 0;return 0;编译多线程程序gcc-o mypthread gcc-o mypthread-lpthread-lpthread mypthread.c mypthread.c线程的退出 调用pthread_exit()结束线程执行 void pthread_exit(void*retval);让线程处理程序返回 使用 pthread_cancel()函数终止其他线程的执行 int pthread_cancel(pthread_t thread);向线程t发送取消请求,默认情况下线程thread自己调用pthread_exit(PTHREAD_CANCE

5、LED),等待线程结束 使用 pthread_join()函数等待被创建的线程结束 pthread_join()函数会挂起创建线程的线程的执行 直到等待到想要等待的子线程 函数原型:int pthread_join(pthread_t th,void*thread_return);线程的分离 主线程可以不断地创建子线程 子线程本身自己有自我回收内存资源的能力 函数原型:int pthread_detach(pthread_t th);pthread_detach()和 pthread_join()一般情况下不能同时使用 获得当前线程的标志pthread_t pthread_self(void)

6、;本函数返回本线程的标识符。在LinuxThreads中,每个线程都用一个pthread_descr结构来描述,其中包含了线程状态、线程ID等所有需要的数据结构,此函数的实现就是在线程栈帧中找到本线程的pthread_descr结构,然后返回其中的p_tid项。一个例子#include#include#include#include#define THREAD_NUMBER 2int retval_hello1=2,retval_hello2=3;void*hello1(void*arg)char*hello_str=(char*)arg;sleep(1);printf(%sn,hello_s

7、tr);pthread_exit(&retval_hello1);void*hello2(void*arg)char*hello_str=(char*)arg;sleep(2);printf(%sn,hello_str);pthread_exit(&retval_hello2);int main(int argc,char*argv)int i;int ret_val;int*retval_hello2;pthread_t ptTHREAD_NUMBER;const char*argTHREAD_NUMBER;arg0=hello world from thread1;arg1=hello w

8、orld from thread2;printf(Begin to create threads.n);ret_val=pthread_create(&pt0,NULL,hello1,(void*)arg0);if(ret_val!=0)printf(pthread_create error!n);exit(1);ret_val=pthread_create(&pt1,NULL,hello2,(void*)arg1);if(ret_val!=0)printf(pthread_create error!n);exit(1);printf(Begin to wait for threads.n);

9、for(i=0;i THREAD_NUMBER;i+)ret_val=pthread_join(pti,(void*)&retval_helloi);if(ret_val!=0)printf(pthread_join error!n);exit(1);else printf(return value is%dn,*retval_helloi);printf(Now,the main thread returns.n);return 0;线程属性的初始化和撤销线程初始化:int pthread_attr_init(pthread_attr_t*attr)初始化线程属性对象attr,并用默认值填充

10、线程撤销:int pthread_attr_destroy(pthread_attr_t*attr)销毁线程属性对象attr。pthread_attr_t定义pthread_attr_t定义: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

11、_attr_t;线程的属性属性名意义 detachstate选择被创建的线程是处于可加入的状态还是选择被创建的线程是处于可加入的状态还是分离状态分离状态 schedpolicy为被创建的线程选择调度策略。为被创建的线程选择调度策略。schedparam为被创建的线程选择调度参数。为被创建的线程选择调度参数。inheritsched选择对新创建的线程的调度策略和调度参数选择对新创建的线程的调度策略和调度参数是否被是否被schedpolicy 和和schedparam 属性决属性决定或者是通过父线程继承而得到的定或者是通过父线程继承而得到的 scope为选择被创建的线程调度竞争范围。为选择被创建的

12、线程调度竞争范围。线程的属性(续)detachstatePTHREAD_CREATE_JOINABLEPTHREAD_CREATE_DETACHED 默认:默认:PTHREAD_CREATE_JOINABLE控制创建的线程是控制创建的线程是joinable态还是态还是detached态态schedpolicySCHED_OTHER(regular,non-realtime scheduling)SCHED_RR (realtime,round-robin)SCHED_FIFO(realtime,first-in first-out)默认:默认:SCHED_OTHER优先级类别优先级类别Sche

13、d param默认:默认:0线程优先级参数线程优先级参数如果如果schedpolicy的值为的值为SCHED_OTHER,schedpolicy此属性无关紧要此属性无关紧要线程创建后可修改此属性线程创建后可修改此属性inheritschedPTHREAD_EXPLICIT_SCHEDPTHREAD_INHERIT_SCHED 默认:默认:PTHREAD_EXPLICIT_SCHED说明此线程优先级是否继承于父线程还是通过说明此线程优先级是否继承于父线程还是通过上面两个属性确定上面两个属性确定scopePTHREAD_SCOPE_SYSTEMPTHREAD_SCOPE_PROCESS 默认:默认

14、:PTHREAD_SCOPE_SYSTEM设置线程绑定状态设置线程绑定状态部分部分Linux不支持不支持PTHREAD_SCOPE_ PROCESS,需要查看,需要查看man相关函数-分离状态设置分离状态:设置分离状态:pthread_attr_setdetachstatepthread_attr_setdetachstateint pthread_attr_setdetachstate(pthread_attr_t*attr,int detachstate);返回值:函数成功返回0;任何其他返回值都表示错误 设置分离状态。参数detachstate的值为:PTHREAD_CREATE_DET

15、ACHED、PTHREAD_CREATE_JOINABLE。获取分离状态:获取分离状态:pthread_attr_getdetachstatepthread_attr_getdetachstateint pthread_attr_getdetachstate(pthread_attr_t*attr,int*detachstate);返回值:函数成功返回0;任何其他返回值都表示错误 取线程分离状态:分离的或是非分离的。相关函数-调度策略设置调度策略:设置调度策略:pthread_attr_setschedpolicypthread_attr_setschedpolicyint pthread_a

16、ttr_setschedpolicy(pthread_attr_t*tattr,int policy);返回值:函数成功返回0;任何其他返回值都表示错误。POSIX标准定义的调度策略有:SCHED_FIFO(先入先出)、SCHED_RR(循环)、SCHED_OTHER(由不同版本的POSIX线程库定义的缺省调度策略)。获取调度策略:获取调度策略:pthread_attr_getschedpolicypthread_attr_getschedpolicyint pthread_attr_getschedpolicy(pthread_attr_t*tattr,int*policy);返回值:函数成

17、功返回0;任何其他返回值都表示错误。相关函数-调度参数设置调度参数:设置调度参数:pthread_attr_setschedparampthread_attr_setschedparamint pthread_attr_setschedparam(pthread_attr_t*tattr,const struct sched_param*param);返回值:函数成功返回0;任何其他返回值都表示错误。属性对象的调度参数定义在param结构中;在这个结构中只定义了优先级priority成员。新创建线程的优先级由属性对象中param结构的priority参数指定。有两种方式可以修改线程的优先级。可

18、以在创建子线程前设置属性对象的优先级参数;也可以先修改父线程的优先级,然后创建子线程。sched_param结构中有可能存放着其他一些调度信息。所以在修改线程属性对象的调度参数前先取现有的调度参数是良好的习惯。一段合理的代码应该是这样的:先取线程属性对象中现有的调度参数,对取出的调度参数进行操作,再用修改过的调度参数重置线程属性对象。获取调度参数:获取调度参数:pthread_attr_getschedparampthread_attr_getschedparamint pthread_attr_getschedparam(pthread_attr_t*tattr,const struct s

19、ched_param*param);返回值:函数成功返回0;任何其他返回值都表示错误。相关函数-域设置域:设置域:pthread_attr_setscopepthread_attr_setscopeint pthread_attr_setscope(pthread_attr_t*tattr,int scope);返回值:函数成功返回0;任何其他返回值都表示错误。指定将来创建的线程是绑定(PTHREAD_SCOPE_SYSTEM)的还是非绑定的(PTHREAD_SCOPE_PROCESS)。在一个进程中可以同时有这两种不同类型的线程。获取域:获取域:pthread_attr_getscopept

20、hread_attr_getscopeint pthread_attr_getscope(pthread_attr_t*tattr,int*scope);返回值:函数成功返回0;任何其他返回值都表示错误。例子:threadattr#include#include#include void*sum_val(void*arg)int sum=0;int i;int count=*(int*)arg;for(i=0;i count;i+)sum=sum+i;printf(sum is%dn,sum);pthread_exit(0);例子:threadattr(续)int main(int argc,

21、char*argv)pthread_t pt;int count=10;int ret_val;pthread_attr_t attr;struct sched_param sp;sp._sched_priority=2;ret_val=pthread_attr_init(&attr);if(ret_val!=0)printf(pthread_attr_init error!n);exit(1);例子:threadattr(续)ret_val=pthread_attr_setdetachstate(&attr,PTHREAD_CREATE_DETACHED);if(ret_val!=0)pri

22、ntf(pthread_attr_setdetachstate error!n);exit(1);ret_val=pthread_attr_setschedpolicy(&attr,SCHED_RR);if(ret_val!=0)printf(pthread_attr_setschedpolicy error!n);exit(1);ret_val=pthread_attr_setschedparam(&attr,&sp);if(ret_val!=0)printf(pthread_attr_setschedparam error!n);exit(1);例子:threadattr(续)ret_va

23、l=pthread_attr_setinheritsched(&attr,PTHREAD_EXPLICIT_SCHED);if(ret_val!=0)printf(pthread_attr_setinheritsched error!n);exit(1);ret_val=pthread_attr_setscope(&attr,PTHREAD_SCOPE_SYSTEM);if(ret_val!=0)printf(pthread_attr_setscope error!n);exit(1);ret_val=pthread_create(&pt,NULL,sum_val,(void*)&count);if(ret_val!=0)printf(pthread_create error!n);exit(1);pthread_attr_destroy(&attr);sleep(5);return 0;

展开阅读全文
温馨提示:
1: 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
2: 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
3.本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
5. 装配图网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
关于我们 - 网站声明 - 网站地图 - 资源地图 - 友情链接 - 网站客服 - 联系我们

copyright@ 2023-2025  zhuangpeitu.com 装配图网版权所有   联系电话:18123376007

备案号:ICP2024067431-1 川公网安备51140202000466号


本站为文档C2C交易模式,即用户上传的文档直接被用户下载,本站只是中间服务平台,本站所有文档下载所得的收益归上传人(含作者)所有。装配图网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。若文档所含内容侵犯了您的版权或隐私,请立即通知装配图网,我们立即给予删除!