版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、ESD_DAY034_ElvisUNIX/LINUX 系统下的C高级编程A.N.E.K本日要点:1、线程-X-X-X-X-X-X-X-X-X-X-X-X-X-X-X-X-X-X-X-X-X-X-X-X-X-X-X-X-X-X-X-X-X-X-X-1.线程1.1基本概念线程是一种轻量级的代码并行的方式。如果需要,同时执行两段或者更多段的代码(代码并行),则必须使用多进程或多线程。Unix/Linux系统更多地采用了多进程,Windows系统更多地采用了多线程。1.2进程和线程的区别:每个进程都有自己独立的资源,比如内存;进程之间不能直接互访,必须使用IPC实现通信,是重量级的。每个线程共享所在进
2、程的资源,自己只需要一个独立的栈即可,是轻量级的1.3系统、进程和线程的关系操作系统支持多个进程并行,每个进程的内部允许多个线程并行。进程本身其实并不能执行代码,只是为主线程(main函数)配齐资源(内存),由主线程负责执行进程的代码。主线程和其他线程的关系:线程之间都是相互独立(如主线程sleep,其他线程也能够继续正常工作),但是又相互影响(如主线程一旦结束,则进程也结束;各个线程之间资源共享)。1.4 CPU只有一个,线程如何运行:代码运行的必备资源:CPU和内存。内存是可分的,支持并行;CPU不可分,不采用特殊处理方法则只能执行一个线程。CPU把自己的时间分成了极小的CPU时间片,每个
3、线程可以拥有时间片,有时间片的线程可以执行极小的的一段时间,时间消耗完了就交给其他有时间片的线程继续运行。严格来说,线程在时间点上是没有并行的,但是时间点无法观察,因此,我们承认线程是并行的。Unix系统提供了完整的线程的一套函数,直接使用即可。多进程步骤:引入头文件pthread.h,提供了libpthread.so库文件1.线程的创建;线程的函数大多数以”pthread_”开头pthread_create()函数 功能:创建一个线程。格式:#include <pthread.h> int pthread_create(pthread_t *thread, const pthre
4、ad_attr_t *attr, void *(*start_routine) (void *), void *arg);注意:第一个参数:一个指针,这是一个传出参数,用来接收线程创建成功后的线程ID,这是一个整数; 第二个参数:一个结构体指针,用来传入要创建的线程的属性,一般情况下使用默认属性即可,一般给NULL即可; 第三个参数:一个函数指针,这个函数指针指向的函数的返回值为void*,参数也是void*。系统启动新线程后,执行某个函数的代码,这个函数有此参数指定,然后对这个函数与主函数并行处理; 第四个参数:为第三个参数指定的函数提供形式参数,与第三个参数联合指定了执行哪个参数,用什么参
5、数;返回值:成功返回0,失败返回错误码。线程的错误处理不使用errno、perror(),而是直接返回错误码。多线程启动时,代码运行是:每个线程内部是顺序执行,线程之间乱序执行。*创建一个新线程,并观察主线程和新线程的运行特点*#include<stdio.h>#include<pthread.h>#include<string.h>void*task(void*p) int i; for(i=0;i<50;i+) printf("task:%dn",i); usleep(1); int main() pthread_t id; /
6、pthread_create函数只是告知系统创建进程,不保证马上运行,通知完了就继续运行下面的代码 int res=pthread_create(&id,NULL,task,NULL); if(res) printf("%sn",strerror(res); else printf("线程成功启动n"); int i; for(i=0;i<50;i+) printf("main:%dn",i); usleep(3); /使用延时保证在其他线程执行结束前,不让主线程结束;因为主线程一旦结束,所有线程都结束 sleep(2)
7、; return 0;在使用线程的参数时,一定要保证这个指针是有效的。当一个线程在通过指针使用一块内存区域时,要确保这块内存不会被其他的线程释放。使用pthread_join()可以让一个线程等待另外一个线程的结束,同时拿到结束线程的返回值。等待的线程处于阻塞的状态。可以用来防止主线程的提前结束。pthread_join()函数功能:使调用线程等待另一个线程的结束,同时拿到结束进程的返回值。格式:#include <pthread.h> int pthread_join(pthread_t thread, void *retval); Compile and link with -
8、pthread.注意:第一个参数:线程ID,这是一个整数; 第二个参数:一个二级指针,用来获取结束线程的返回值(返回值是一个void*类型),当给NULL时,表示不获取结束线程的返回值; 编译和链接时需要使用:-pthread;返回值:成功返回0,失败返回错误码。线程的错误处理不使用errno、perror(),而是直接返回错误码。*获取线程的返回值*#include<stdio.h>#include<pthread.h>#include<string.h>void*task(void*p) return "Komachi"void*ta
9、sk1(void*p) static int sum=0; int i=0; for(i=0;i<=100;i+) sum=sum+i; return ∑int main() pthread_t id,id1; pthread_create(&id,NULL,task,NULL); char*res=NULL;/定义一个和线程返回值类型即可 pthread_join(id,(void*)&res); printf("%sn",res); pthread_create(&id1,NULL,task1,NULL); int *sum
10、=NULL; pthread_join(id1,(void*)&sum); printf("sum=%dn",*sum); return 0;1.2.线程的退出使用pthread_exit()函数或者直接return。线程也可能被其他线程取消。线程的退出不能用exit(),因为exit()退出的是进程。pthread_exit()函数 功能:创建一个线程。格式:#include <pthread.h> void pthread_exit(void *retval); Compile and link with -pthread.注意:一个参数:一个指针,
11、代表此退出线程的返回值(void*类型); 编译和链接时需要使用:-pthread;返回值:无返回值 1.3.线程的资源回收有三种方式:1).分离状态的线程(pthread_detach()函数)一结束就立刻回收;2).被pthread_join()的进程,pthread_join()结束后立即回收;3).其他情况,不确定什么时候时候。经验:一个线程最后detach或者join。先join后detach,detach无效;先detach后join,join无效。pthread_detach()函数 功能:分离线程,同时在线程结束时立刻回收其资源。格式:#include <pthread.
12、h> int pthread_detach(pthread_t thread); Compile and link with -pthread.注意:一个参数:线程ID,这是一个整数; 编译和链接时需要使用:-pthread;返回值:成功返回0,失败返回错误码。线程的错误处理不使用errno、perror(),而是直接返回错误码。*使用detach或者join回收线程资源*#include<stdio.h>#include<stdlib.h>#include<pthread.h>#include<string.h>void*task(voi
13、d*p) int i; for(i=0;i<30;i+) printf("task:%dn",i); usleep(100000); int main() pthread_t id; int res=pthread_create(&id,NULL,task,NULL); if(res) printf("%sn",strerror(res); exit(-1); /pthread_detach(id);/从程序结果来看并没有明显差异 pthread_join(id,NULL);/可以看到子线程没有结束时,主线程处于阻塞状态 int i; fo
14、r(i=0;i<30;i+) printf("main:%dn",i); usleep(100000); return 0;线程的取消:(了解)pthread_cancel()函数-取消线程(需要设置可以被取消)pthread_setcancelstate()函数-设置一个线程是否可以被取消pthread_setcanceltype()函数-设置取消类型,立即/延后取消1.5线程同步因为线程是共享进程的资源的,当多个线程访问相同的资源时,有可能出现资源的冲突。线程同步就是协调多个线程,防止数据的冲突(不一致,不完整)。线程同步的解决方案其实就是变并行为串行。优点:保证
15、了数据的有效性和一致性;缺点:效率大幅降低;线程同步技术主要包括:互斥量mutex、信号量、条件变量。互斥量也叫互斥锁,使用步骤:1.定义一个互斥量:pthread_mutex_t lock;2.初始化互斥量:a.pthread_mutex_init(&lock,NULL);/第二个参数是一个指针,使用默认的即可NULLb.声明的同时用宏赋值:pthread_mutex_t lock=PTHTEAD_MUTEX_INITIALIZER;3.加锁:pthread_mutex_lock(&lock),无法上锁则阻塞;4.访问共享资源;5.解锁:pthread_mutex_unloc
16、k(&lock);6.释放互斥量的资源:pthread_mutex_destroy(&lock);*使用互斥量来保证线程同步*#include<stdio.h>#include<stdlib.h>#include<pthread.h>char*data5;/字符串数组,用来存放名字int ind=0;/数组中的元素个数/1.声明互斥量,因为每个线程都要使用,因此可定义成全局变量pthread_mutex_t lock;void*task(void*p) /3.使用互斥量上锁 pthread_mutex_lock(&lock); /4.
17、使用共享资源 /放入名字 dataind=(char*)p; /在不采用线程同步时 /id1线程先执行到这里卡住 /模拟CPU卡顿,此时主线程或者id2线程执行 /此时ind为1,当id2线程也执行到这里时ind还是为1,因此id1和id2同时将数据放入了data1中 usleep(1000); /当id1和id2卡顿结束后,ind会在每个线程加1 /人数加1 /最终ind=3,而此时data2=NULL;如果打印data2将会出现段错误 ind+; /5.解除互斥量的锁 pthread_mutex_unlock(&lock);int main() /2.初始化互斥量 pthread_mutex_init(&lock,0); dataind="liubei" ind+; pthread_t id1,id2; pthread_create(&id1,NULL,task,"guanyu"); pthread_create(&id2,NULL,task,"zhangfei"); pthread_join(id1,NULL); pthread_join(id2,NULL); /6.释放互斥量 pthr
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 专项消防安全方案
- 格上矩阵关键问题与应用的深度剖析
- 核酸适体定向进化新方法:从原理到生物医学应用的深度剖析
- 2026届浙江省绍兴上虞区四校联考中考四模数学试题含解析
- 消杀作业安全培训教育课件
- 2026届北京六十六中学中考二模生物试题含解析
- 株洲市高层次人才队伍建设政策的深度剖析与优化路径研究
- 栓(铆)接钢桥超声波无损检测可靠性的多维度探究与提升策略
- 树突状细胞介导CTL对白血病细胞生长抑制的体内外研究:机制与展望
- 2026届山东省济宁市金乡县重点中学中考生物押题试卷含解析
- 弱电包清工施工合同范本
- 2025届山东省泰安市高三二模生物试题(解析版)
- DB1304T 400-2022 鸡蛋壳与壳下膜分离技术规程
- 输液病人外带药协议书
- 别墅装修全案合同样本
- 2025骨质疏松症的诊治规范
- 2025年职业病防治法宣传周
- 英语-北京市朝阳区2025年高三年级第二学期质量检测一(朝阳一模)试题和答案
- 医院培训课件:《医疗废物分类及管理》
- 大学生职业生涯规划 课件 第三章 职业探索
- 《接触网施工》课件 4.8.1 交叉线岔安装
评论
0/150
提交评论