版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
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(ne
3、w thread:); printids(new 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 crea
4、te thread: %sn,strerror(err); return 1; return 1; sleep(1); 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(pthr
5、ead_t thread); 向线程t发送取消请求,默认情况下线程thread自己调用pthread_exit(PTHREAD_CANCELED), 等待线程结束 使用 pthread_join() 函数等待被创建的线程结束 pthread_join() 函数会挂起创建线程的线程的执行 直到等待到想要等待的子线程 函数原型 : int pthread_join(pthread_t th, void *thread_return); 线程的分离 主线程可以不断地创建子线程 子线程本身自己有自我回收内存资源的能力 函数原型:int pthread_detach(pthread_t th); pth
6、read_detach() 和 pthread_join() 一般情况下不能同时使用 获得当前线程的标志pthread_t pthread_self(void);本函数返回本线程的标识符。 在LinuxThreads中,每个线程都用一个pthread_descr结构来描述,其中包含了线程状态、线程ID等所有需要的数据结构,此函数的实现就是在线程栈帧中找到本线程的pthread_descr结构,然后返回其中的p_tid项。一个例子#include #include #include #include #define THREAD_NUMBER 2int retval_hello1= 2, ret
7、val_hello2 = 3;void* hello1(void *arg) char *hello_str = (char *)arg; sleep(1); printf(%sn, hello_str); 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
8、 ret_val; int *retval_hello2; pthread_t ptTHREAD_NUMBER; const char *argTHREAD_NUMBER; arg0 = hello world from thread1; arg1 = hello world 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
9、); 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); for(i = 0; i THREAD_NUMBER; i+) ret_val = pthread_join(pti, (void *)&retval_helloi); if (ret_val != 0) printf(pthread_join
10、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,并用默认值填充线程撤销:int pthread_attr_destroy(pthread_attr_t *attr) 销毁线程属性对象attr。pthread_attr_t定义pthread_attr_t定义:typ
11、edef 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选择被创建的线程是处于可加入的状态还是选择被创建的线程是处于可加入的状态还是分离状态分离状态 schedpolicy
12、为被创建的线程选择调度策略。为被创建的线程选择调度策略。 schedparam为被创建的线程选择调度参数。为被创建的线程选择调度参数。 inheritsched选择对新创建的线程的调度策略和调度参数选择对新创建的线程的调度策略和调度参数是否被是否被schedpolicy 和和schedparam 属性决属性决定或者是通过父线程继承而得到的定或者是通过父线程继承而得到的 scope为选择被创建的线程调度竞争范围。为选择被创建的线程调度竞争范围。线程的属性(续)detachstatePTHREAD_CREATE_JOINABLEPTHREAD_CREATE_DETACHED 默认:默认:PTHRE
13、AD_CREATE_JOINABLE控制创建的线程是控制创建的线程是joinable态还是态还是detached态态schedpolicySCHED_OTHER (regular, non-realtime scheduling)SCHED_RR (realtime, round-robin)SCHED_FIFO (realtime, first-in first-out) 默认:默认:SCHED_OTHER优先级类别优先级类别Sched param默认:默认:0线程优先级参数线程优先级参数如果如果schedpolicy的值为的值为SCHED_OTHER,schedpolicy此属性无关紧要此
14、属性无关紧要线程创建后可修改此属性线程创建后可修改此属性inheritschedPTHREAD_EXPLICIT_SCHEDPTHREAD_INHERIT_SCHED 默认:默认:PTHREAD_EXPLICIT_SCHED说明此线程优先级是否继承于父线程还是通过说明此线程优先级是否继承于父线程还是通过上面两个属性确定上面两个属性确定scopePTHREAD_SCOPE_SYSTEMPTHREAD_SCOPE_PROCESS 默认:默认:PTHREAD_SCOPE_SYSTEM设置线程绑定状态设置线程绑定状态部分部分Linux不支持不支持PTHREAD_SCOPE_ PROCESS,需要查看,
15、需要查看man相关函数-分离状态设置分离状态:设置分离状态:pthread_attr_setdetachstatepthread_attr_setdetachstateint pthread_attr_setdetachstate(pthread_attr_t *attr, int detachstate); 返回值:函数成功返回0;任何其他返回值都表示错误 设置分离状态。参数detachstate的值为:PTHREAD_CREATE_DETACHED、PTHREAD_CREATE_JOINABLE。获取分离状态:获取分离状态:pthread_attr_getdetachstatepthrea
16、d_attr_getdetachstateint pthread_attr_getdetachstate(pthread_attr_t *attr, int *detachstate); 返回值:函数成功返回0;任何其他返回值都表示错误 取线程分离状态:分离的或是非分离的。相关函数-调度策略设置调度策略:设置调度策略:pthread_attr_setschedpolicypthread_attr_setschedpolicyint pthread_attr_setschedpolicy(pthread_attr_t *tattr, int policy); 返回值:函数成功返回0;任何其他返回
17、值都表示错误 。POSIX标准定义的调度策略有:SCHED_FIFO(先入先出)、SCHED_RR(循环)、SCHED_OTHER(由不同版本的POSIX线程库定义的缺省调度策略)。获取调度策略:获取调度策略:pthread_attr_getschedpolicypthread_attr_getschedpolicyint pthread_attr_getschedpolicy(pthread_attr_t *tattr, int *policy); 返回值:函数成功返回0;任何其他返回值都表示错误 。相关函数-调度参数设置调度参数:设置调度参数:pthread_attr_setschedpa
18、rampthread_attr_setschedparamint pthread_attr_setschedparam(pthread_attr_t *tattr, const struct sched_param *param); 返回值:函数成功返回0;任何其他返回值都表示错误 。属性对象的调度参数定义在param结构中;在这个结构中只定义了优先级priority成员。新创建线程的优先级由属性对象中param结构的priority参数指定。有两种方式可以修改线程的优先级。可以在创建子线程前设置属性对象的优先级参数;也可以先修改父线程的优先级,然后创建子线程。sched_param结构中有可
19、能存放着其他一些调度信息。所以在修改线程属性对象的调度参数前先取现有的调度参数是良好的习惯。一段合理的代码应该是这样的:先取线程属性对象中现有的调度参数,对取出的调度参数进行操作,再用修改过的调度参数重置线程属性对象。获取调度参数:获取调度参数:pthread_attr_getschedparampthread_attr_getschedparamint pthread_attr_getschedparam(pthread_attr_t *tattr, const struct sched_param *param); 返回值:函数成功返回0;任何其他返回值都表示错误 。相关函数-域设置域:设
20、置域:pthread_attr_setscopepthread_attr_setscopeint pthread_attr_setscope(pthread_attr_t *tattr, int scope); 返回值:函数成功返回0;任何其他返回值都表示错误 。指定将来创建的线程是绑定(PTHREAD_SCOPE_SYSTEM)的还是非绑定的(PTHREAD_SCOPE_PROCESS)。在一个进程中可以同时有这两种不同类型的线程。获取域:获取域:pthread_attr_getscopepthread_attr_getscopeint pthread_attr_getscope(pthre
21、ad_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, char *argv) pthrea
22、d_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) printf(pthread_attr_setdetachstate error!n); exit(1);
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 武钢实习报告4篇
- 水产品行业产能扩张与投资布局考核试卷
- 煤炭行业的价值链与供应链考核试卷
- 油炸食品行业对消费者行为影响研究考核试卷
- 货物运输企业安全风险分级管控和隐患排查治理双体系方案全套资料(2019-2020新标准完整版)
- 渔业与社会福利的公平分配考核试卷
- ccp相关课件教学课件
- 饭店员工培训方案
- 淮阴工学院《控制工程与测试技术》2021-2022学年期末试卷
- 淮阴工学院《建筑工程施工》2023-2024学年第一学期期末试卷
- sch壁厚等级对照表
- 高新技术企业认定自我评价表
- 药物分类目录
- 中石油-细节管理手册 03
- 柿子品种介绍PPT课件
- 全国重点文物保护单位保护项目安防消防防雷计划书
- 护士对预防患者跌倒的问卷调查表
- 道路开口施工方案
- 天然气脱硫(课堂运用)
- 幼儿园教师师德师风考核表(共2页)
- 城镇职工医疗保险运行中的问题分析及措施
评论
0/150
提交评论