linux_多进程多线程及其同步

上传人:re****.1 文档编号:522489623 上传时间:2023-03-01 格式:DOCX 页数:40 大小:145.85KB
返回 下载 相关 举报
linux_多进程多线程及其同步_第1页
第1页 / 共40页
linux_多进程多线程及其同步_第2页
第2页 / 共40页
linux_多进程多线程及其同步_第3页
第3页 / 共40页
linux_多进程多线程及其同步_第4页
第4页 / 共40页
linux_多进程多线程及其同步_第5页
第5页 / 共40页
点击查看更多>>
资源描述

《linux_多进程多线程及其同步》由会员分享,可在线阅读,更多相关《linux_多进程多线程及其同步(40页珍藏版)》请在金锄头文库上搜索。

1、Linux 多进程、多线程及网络编程指南1、 进程(多进程)2、 线程(多线程)3、 进程间通信4、 并发程序的同步5、 socket网络编程1、进程1.1进程定义进程是程序在计算机上的执行活动,是一个运行着一个或多个线程的地址空间和这些线程所需要的系统资源,其中包括程序代码、数据、变量、打开文件的文件描述符、和环境。1.2进程的五种状态在五状态进程模型中,进程状态被分成下列五种状态。进程在运行过程中主要是在就绪、运行和阻塞三种状态间进行转换。创建状态和退出状态描述进程创建的过程和进程退出的过程。1)运行状态(Running):进程占用处理器资源;处于此状态的进程的数目小于等于处理器的数目。在

2、没有其他进程可以执行时(如所有进程都在阻塞状态),通常会自动执行系统的空闲进程。2)就绪状态(Ready):进程已获得除处理器外的所需资源,等待分配处理器资源;只要分配了处理器进程就可执行。就绪进程可以按多个优先级来划分队列。例如,当一个进程由于时间片用完而进入就绪状态时,排入低优先级队列;当进程由IO操作完成而进入就绪状态时,排入高优先级队列。3)阻塞状态(Blocked):当进程由于等待I/O操作或进程同步等条件而暂停运行时,它处于阻塞状态。4)创建状态(New):进程正在创建过程中,还不能运行。操作系统在创建状态要进行的工作包括分配和建立进程控制块表项、建立资源表格(如打开文件表)并分配

3、资源、加载程序并建立地址空间表等。5)退出状态(Exit):进程已结束运行,回收除进程控制块之外的其他资源,并让其他进程从进程控制块中收集有关信息(如记帐和将退出代码传递给父进程)。进程三种状态的转换如图所示:就绪执行等待时间片到因等待时间发生而唤醒因等待时间发生而睡眠调度到进程三种状态的转换关系1.3 进程的结构Linux系统是一个多进程的系统,进程间有并行性、互不干扰等特点。通俗的说进程间是分离的任务,拥有各自的权力和责任,每个进程运行在各自独立的虚拟地址空间,一个进程发生了异常,它也不会影响到系统中的其他进程。Linux进程包含三个段:数据段、代码段、堆栈段。数据段:存放的是全局变量、常

4、数、static 定义的静态变量和动态分配的数据(malloc函数取得的空间)等。代码段:存放的是程序代码的数据。堆栈段:存放的是子程序的返回地址、子程序的参数以及程序的局部变量。1.4 进程的执行模式当一个任务(进程)执行系统调用而陷入内核代码中执行时,我们就称进程处于内核运行态(或简称为内核态)。此时处理器处于特权级最高的(0级)内核代码中执行。当进程处于内核态时,执行的内核代码会使用当前进程的内核栈。每个进程都有自己的内核栈。当进程在执行用户自己的代码时,则称其处于用户运行态(用户态)。即此时处理器在特权级最低的(3级)用户代码中运行。当正在执行用户程序而突然被中断程序中断时,此时用户程

5、序也可以象征性地称为处于进程的内核态。因为中断处理程序将使用当前进程的内核栈。这与处于内核态的进程的状态有些类似。在内核模式下运行的进程可以执行机器的特权指令,并且此时该进程的运行不受用户的干扰,即使是root用户也不能干扰内核模式下程序的运行。进程上下文和中断上下文处理器总处于以下状态中的一种:1、内核态,运行于进程上下文,内核代表进程运行于内核空间;2、内核态,运行于中断上下文,内核代表硬件运行于内核空间;3、用户态,运行于用户空间。1.4 创建新进程通过fork调用创建一个新进程,这个系统调用复制当前进程在系统表中创建一个新的表项,新表项中的许多属性与当前进程是相同的。新进程与原进程几乎

6、一样,但还是有不同之处。父子进程的异同:继承属性差异真实的用户ID和组ID,有效用户ID和组ID进程组IDSESSION ID所打开文件及文件的偏移量控制终端设置用户ID和设置组ID标记位根目录与当前工作目录文件缺省创建的权限掩码可访问的内存段环境变量及其他资源分配进程ID父进程ID子进程运行的时间记录父进程对文件的锁fork 和 exec函数族结合在一起使用就是创建新进程所需要的一切了,值得注意的是exec函数执行之后原进程之后的代码将不会被执行。 创建一个新进程也可以使用vfork,但vfork并不完全拷贝父进程的数据段而是和父进程共享数据段。这是因为vfork函数是与exec函数族相连,

7、创建执行另一个程序的新进程。并且调用vfork对于父子进程的执行次序有限制,调用vfork时,父进程被挂起,子进程运行至调用exec函数族或调用exit时解除这种状态。而fork是不会阻塞调用进程的,父子进程的执行顺序是不确定的。1.5 僵尸进程一个进程结束了,但是他的父进程没有等待(调用wait / waitpid)他, 那么他将变成一个僵尸进程. 但是如果该进程的父进程已经先结束了,那么该进程就不会变成僵尸进程, 因为每个进程结束的时候,系统都会扫描当前系统中所运行的所有进程, 看有没有哪个进程是刚刚结束的这个进程的子进程,如果是的话,就由Init 来接管他,成为他的父进程。僵尸进程过多会

8、严重占用系统的进程ID号,从而导致整个系统不能工作。僵尸进程的避免 1)父进程通过wait和waitpid等函数等待子进程结束,这会导致父进程挂起。 2)如果父进程很忙,那么可以用signal函数为SIGCHLD安装handler,因为子进程结束后, 父进程会收到该信号,可以在handler中调用wait回收。 3)如果父进程不关心子进程什么时候结束,可用signal(SIGCHLD, SIG_IGN)通知内核,那么子进程结束后,内核会回收,并不再给父进程发送信号。 4)还有一些技巧,就是fork两次,父进程fork一个子进程,然后继续工作,子进程fork一 个孙进程后退出,那么孙进程被ini

9、t接管,孙进程结束后,init会回收。不过子进程的回收 还要自己做。避免僵尸进程示例如下:开始pid=fork()pid 0pid = 0pid安装信号SIGCHLD的处理函数sleep 2 secDo working向父进程发送SIGCHLD信号sleep 1 sec结束调用wait或waitpid清理子进程1.5 等待进程处理多进程时,经常用到有关进程间等待的操作,进程等待可以是父进程等待子进程也可以是进程组成员间的等待。进程等待常用的系统调用是wait和waitpid。pid_t wai(int *status); 调用专用于等待一个子进程,调用wait的时候,调用者父进程将被挂起,直到

10、该进程的一个子进程结束时,该调用返回。如果调用没有子进程,则错误返回,调用成功,如果status指针不为空,那么被等待退出的进程的状态信息将被写入status所指向的位置,调用失败时,返回-1。pid_t waitpid(pid_t pid, int *status, int options); 该调用比wait灵活一些,可以用来等待制定进程,且可以使进程不挂起而立刻返回。参数pid用于指定要等待的进程,参数status类似wait系统调用参数的作用,参数options则用于改变waitpid的行为,比如选项WNOHANG,它的作用是防止waitpid调用将调用者的执行挂起。可以使用该选项检查

11、某个特定子进程是否退出。如果子进程没有结束或意外终止,它返回0,否则返回child_pid,如果waitpid失败,它将返回-1,并设置errno。失败的情况可能是:没有子进程(errno设置为ECHILD)、调用被某个信号中断(EINTR)或选项参数无效(EINVAL)。头文件sys/wait.h 文件中定义的宏可以解释程序退出的原因,如:WIFEXITED(stat_val) 如果子进程正常结束,它就取一个非零值。WEXITSTATUS(stat_val) 如果WIFEXITED非零,它返回子进程的退出码。其他有关进程退出宏的用法可查阅相关文档。1.6 终止进程可以使用exit(int s

12、tatus)或_exit(int status)系统调用来终止进程,当程序执行到exit和_exit时,进程会无条件的停止所有操作,清理包括PCB在内的各种数据结构,并终止调用进程的运行。但这两个函数有一些区别,如下图所示:exit(int status)函数与_exit(int status)函数的最大区别就在于,exit()函数在调用exit系统调用之前要检查文件的打开情况,把文件缓冲区里的内容写回到文件中。参数status可以传递进程结束时的状态,0表示正常结束,其他数值表示出现了错误,进程非正常结束,在实际编程中,可以用wait系统调用接受子进程的返回值,从而针对不同情况进程不同处理。

13、进程运行中调用退出处理函数exit(int status)_exit(status)清理I/O缓冲调用exit系统调用进程终止运行1.7编写多进程程序目的:通过编写一个多进程程序进一步加深linux中多进程编程的步骤,该程序设计到fork、exec、wait、waitpid等函数的使用。内容:一个父进程,fork两个子进程,其中一个子进程运行”ls -l”指令,另一个子进程暂停5s后异常退出,父进程并不阻塞自己,并等待子进程的退出信息,待收集到该信息,父进程就返回。1) 流程图如下:开始P1=fork()P10P1=0 P1 P2P2=fork()P2=fork() P2P2=0P2=0P20P20sleep 2 secexeclp()P=waitpid(P2,NULL,WNOHANG)execlp()noP=0yessleep 1 secyesP=0n

展开阅读全文
相关资源
正为您匹配相似的精品文档
相关搜索

最新文档


当前位置:首页 > 机械/制造/汽车 > 工程材料

电脑版 |金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号