嵌入式LINUX学习笔记

整理文档很辛苦,赏杯茶钱您下走!

免费阅读已结束,点击下载阅读编辑剩下 ...

阅读已结束,您可以下载文档离线阅读编辑

资源描述

进程进程的特点:动态性、并发性、独立性、异步性状态(三态)进程ID:进程ID(PID):标识进程的唯一的数字父进程的ID:(PPID)启动进程的用户ID(UID)进程互斥:当有若干进程都要使用某一共享资源时,任何时刻最多允许一个进程使用,其它要使用该资源的进程必须等待直到该资源释放了该资源为止。(临界资源)临界资源:同一时刻只允许一个进程,访问的资源称为临界资源临界区:进程中访问临界资源的那段程序代码称为临界区为了实现对临界资源的互斥访问应保证诸进程互斥地进入各自的临界区进程的同步:一组并发的进程按一定的顺序执行的过程为进程间的同步。具有同步关系的一组并发进程称为合作进程,合作进程间互相发送信号称为信号或事件进程的调度:概念:按一定的算法,从一组待运行的进程中选出一个来占有CPU运行调度方式:抢占式、非抢占式调度算法:先来先服务调度算法短进程优先调度算法(即运行时间短的优先)高优先级优先调度算法(数值越小优先级越高LINUX中)时间片轮转法(分时利用)死锁多个进程因竞争资源而形成的一种僵死局,若无外力作用,这些进程都将永远不能向前推进。竞争资源预防是防止死锁的最好的办法进程的控制编程#includesys/types.h#includeunistd.hpid_tgetpid(void)//获取当前进程的IDpid_tgetppid(void)//获取当父进程的ID)(返回进程IDint型)进程的创建——fork()#includeunistd.hpid_tfork(void)//创建子进程注:fork函数一次调用两次返回#includesys/types.h#includeunistd.hvoidmain(void){pid_tpid;intcount=0;pid=fork();count++;prinft(count=%d\n,count);exit(0);}运行的结果:count=1count=1分析:子进程的数据空间、堆栈空间都会从父进程中得到一个拷贝而不是共享。在子进程中对count+1并没有影响到父进程中的count的值,父进程中仍为0count++;prinft(count=%\n,count);这段程序分别将在父子进程中运行互相独立vfork()创建子进程#includesys/types.h#includeunistd.hpid_tvfork(void)forkPKvfork区别:1、fork子进程拷贝父进程的数据段vfork子进程共享父进程的数据段2、fork父、子进程执行的次序不确定vfork子进程先运行,父进程后运行#includesys/types.h#includeunistd.hintmain(void){pid_tpid;intcount=0;pid=vfork();if(pid==0){count++;prinft(count=%\n,count);_exit(0);}elseif(pid0){count++;prinft(count=%\n,count);exit(0);}}运行结果:count=1count=2count++;prinft(count=%\n,count);这段程序:先在子进程是运行count=1;然后在父进程中运行,由于调用vfork子进程共享父进程的数据段,所以count再次自增1,count=2exec函数族:exec用被执行的程序替代调用它的程序forkPKexec区别:fork创建一个新的进程产生新的PIDexec启动一个新的程序,替换原有的进程因此进程的PID不会改变exec函数族:头文件:#includeunistd.h函数名函数原型execlintexecl(constchar*path,const*arg1,….)execlpintexeclp(constchar*path,const*arg1,….)execvintexecv(constchar*path,const*argv[])说明:execl:intexecl(constchar*path,const*arg1,….)参数:path被执行程序名(含完整路径)arg1~~argn被执行程序所需要的命令行参数,含函数名,以空指针(NULL)结束eg:execl(/bin/ls,ls,-al,/etc/passwd,(char*)0);相当于命令行:ls–al/etc/passwdexeclp:intexeclp(constchar*path,const*arg1,….)参数:path被执行程序名(不含完整路径,将从path环境变量中查找该程序)arg1~~argn被执行程序所需要的命令行参数,含函数名,以空指针(NULL)结束eg:execlp(ls,ls,-al,/etc/passwd,(char*)0);相当于命令行:ls–al/etc/passwdexecv:intexecv(constchar*path,const*argv[])参数:path被执行程序名(含完整路径)argv[]被执行程序所需要的命令行参数组eg:char*argv[]={ls,-al,/etc/passwd,(char*)0};execv(/bin/ls,argv)相当于命令行:ls–al/etc/passwdsystem函数#includestdlib.hintsystem(constchar*string)会产生一个新的子进程功能:调用fork函数产生一个子进程,由子进程调用/bin/sh–cstring来执行参数string所代表的命令system(ls–al/etc/passwd)相当于命令行:ls–al/etc/passwd进程等待:#includesys/types.h#includesys/wait.hpid_twait(int*status)功能:阻塞该进程,直到其某个子进(任意的一个)程退出返回:子进程的PID#includestdio.h#includestdlib.h#includesys/types.h#includeunistd.h#includesys/wait.hvoidmain(){pid_tpc,pr;pc=fork()if(pc==0){printf(Thisischildprocesswithof%d/n,getpid());sleep(10);}elseif(pc=0){pc=wait(NULL);printf(Icatchedachildaprocesswithpidof%d\n,pr);}exit(0);}进程间的通信目的:1.、数据的传输:一个进程需要将它的数据发送给另一进程2、资源共享:多个进程之间共享同样的资源3、通知事件:一个进程需要向另一个或一组进程发送信息通知它们发生了某种事件4、进程的控制:有些进程希望完全控制另一个进程的执行(debug进程)此时控制进程希望能够拦截另一个进程所有操作并能够即时知道它的状态改变。Linux中的进程机制:1、unix进程间的通信2、基于systemV进程间的通信3、Posix进程间的通信(portableoperatingsysteminterface)方式:1、管道(pipe)和有名管道(FIFO)2、信号(singal)3、信息队列4、共享内存5、信号量6、套接字(socket)Pipe(管道)Pipe:单向、先进先出、它把一个进程的输出和另一个进程的输入连接在一起,一个进程(写进程)在管道的尾部写入数据,另一个进程(读进程)从管道的头部读出数据总结:从尾写,从头读数据被一个进程读出后,将被从管道中删除,其它读进程将不能读到这些数据,管道提供了简单的流控制机制,进程试图读空管道时,进程将阻塞,同样管道已经满时,进程再次试图向管道写入数据,进程将阻塞。Pipe:无名管道:父子进程间的通信有名管道:任意两个进程间的通信无名管道的创建:pipe()函数intpipe(intfiledis[2])创建了两个文件描述符:filedis[0]、filedis[1]filedis[0]用于读位于pipe的头filedis[1]用于写位于pipe的尾管道的关闭:使用close()函数逐个关闭两个文件描述符close(filedis[0]);close(filedis[1]);pipe的读写:管道用于不同进程的通信通常是先创建一个管道,再通过fork()函数创建一个子进程该子进程会继承父进程所创建的管道注意:必须在系统调用fork()前调用pipe(),否则子进程将不会继承相应的文件描述符例:命名管道FIFO命名管道与无名管道基本相同但不同的是:无名管道只能由父子进程使用,但是通过命名管道可以在不相关的进程间交换数据。创建:#includesys/types.h#includesys/stat.hintmkfifo(constchar*pathname,mode_tmode)pathname:FIFO的文件名mode:属性(间文件操作)一旦创建FIFO就可以用open()打开它,一般文件访问函数(closereadwrite等)都可以用于FIFO。当打开FIFO的非阻塞标志(O_NONBLOCK)将对以后的读写产生如下的影响:1、没有使用O_NONBLOCK访问要求无法满足时进程将阻塞,如果试图读取空的FIFO将导致进程阻塞2、使用了O_NONBLOCK访问要求无法满足时不阻塞立刻出错返回:errno=ENXIO信号通信信号处理方式:1、忽略此信号对信号不做任何处理,但有两个不能忽略即SIGKILL和SIGSTOP。SIGKILL:用于终止进程的执行。与其他的信号不通,该信号不能被阻塞、忽略、和捕捉。这个信号往往被root用户或其他系统管理人员用于终止某个使用其他终止信号无法结束的进程SIGSTOP:停止进程的执行,该进程并没有结束,只是出于停止状态。该信号不能被阻塞、忽略、和捕捉。2、执行用户希望的动作通知内核在某种信号发生时,调用一个用户函数,在用户函数中执行用户希望的处理。3、执行系统默认的动作对大多数信号系统默认的,动作都是终止该进程信号的发送发送信号的主要函数:kill()、raise()区别:kill()可以向本进程发送信号,也可以向别的进程发送信号raise()只能向本进程发送信号函数原型#includesys/types.h#includesignal.hintkill(pid_tpid,intsigno)intraise(intsigno)kill()的pid参数的四种情况:1、pid0将信号发送给进程ID为pid的进程2、pid==0将信号发送同组进程3、pid0将信号发送给其进程组ID=|pid|绝对值的进程4、pid==-1将信号发给所有进程alarm()使用alarm()函数可以设置一个时间值(闹钟时间)当所设置的时间到了,产生一个SIGALRM信号,如果不捕捉信号,则默认动作是终止进程#includeunistd.hunsignedintalarm(unsignedintseconds)seconds:秒,经过指定seconds秒后会产生信号SIGALRMpause()pause()函数调用进程挂起直到捕捉到一个信号#includeunistd.hintpause(void)通常可以用于判断信号是否已到信号的处理不系统捕捉互某一个信号时,可以忽略或使用指定的处理函数来处理该信号,或使用系统默认的方式信号处理的主要的两种方法1、使用简单的signal函数2、使用信号集函数组signal()函数头文件#includesignal.h函数原型Void(*signal(intsignum,void(*func)(int)))(int)函数的传入值signum:指定信号代码funcSIG_IGN:忽略该信号SIG_DFL:采用系统默认的处理方式自定义的信号处理函数找指针函数返回成功:以前的信号处理配置出错:-1

1 / 39
下载文档,编辑使用

©2015-2020 m.777doc.com 三七文档.

备案号:鲁ICP备2024069028号-1 客服联系 QQ:2149211541

×
保存成功