问题解答:
1.exit(状态码)返回状态码有什么意义?
返回值被系统得到:系统根据状态码进行日志记录。
返回值被调用者得到:system/wait程序会根据返回状态码进行对应处理。
exit(状态码) == main函数中的return 状态码;
2.状态码的第二个字节才是exit()的返回值或者return值。
一、进程的基本控制
1.进程的常见控制函数
1.1为什么需要控制进程
1.2pause/sleep/usleep
1.3atexit on_exit
2.进程与文件锁
在多文件下文件读写是共享的。
问题:
怎么知道一个文件正在被另外进程读写?
解决方案:
文件锁。(建议锁)
API:
fcntl(文件锁受内核参数影响)
编程技巧:
对一个文件加锁
判定一个文件是否存在锁
函数说明:
intfctnl(
intfd, //被加锁的文件描述符号
intcmd,/ //锁的操作方式:F_SETLK(如果已经存在,异常返回) F_UNLK F_SETLKW(如果已经加锁,则阻塞等待)
structflock *lk); //锁的描述
返回值:
0:加锁成功
-1:加锁失败
案例:
写两个程序:
A:加锁
B:获取锁的信息
锁也是一个进程可以共享的信息。
二、信号
1.信号的作用
背景:
进程之间通信比较麻烦。
但进程之间又必须通信,比如父子进程之间。
作用:
通知其他进程响应。进程之间通信机制。
信号:
接受信号进程马上停止。调用信号处理函数。
信号处理函数:
默认处理函数。
打印信号信息,退出进程。
用户处理函数。
中断:
软中断。
案例:
1.进程之中,默认信号处理
2.进程之中,用户信号处理(中断)
kill-s 信号进程ID
kill-信号进程ID
信号: 数字 1-31 34-64
宏 SIGINT=2
ctrl+c发送信号2 SIGNIT
kill-l 查看所有信号
信号:SIGKILLSIGSTOP 不能被处理
案例:
发送信号
intkill(pid_t pid, int s)
进程ID:
>0:发送信号到指定进程
=0:发送信号到该进程所在进程组的所有进程
=-1:发送给所有进程,除init外
<0:发送给指定的进程组(组ID=绝对值)
2.信号的发送与安装
signal
kill
3.信号的应用
3.1延时器 timeout
SIGALRM
信号发出函数:alarm
3.2定时器 setitimer
intsetitemer(int which, //计时方式 (ITIMER_REAL /ITIMER_VIRTUAL /ITMER_PROF)
conststrcut itimerval *val, //定时器的时间参数
structitimer *oldval); //返回原来设置的定时器 (如果=NULL, 则不返回)
structitimerval
{
structtimeval it_interval;//间隔时间
structtimeval it_value//延时时间
}
structtimeval
{
longtv_sec;
longtv_usec;
}
信号应用:
系统与应用程序之间
应用程序与应用程序
父子进程之间
案例1:
使用定时器信号,实现多任务。
实现:
实现7位随机数
使用中断实现时间的显示
案例2:
实现父子进程之间通信
控制进程
sleep与pause函数被信号影响后
sleep不再sleep,pause不再pause
练习:
1.在curses显示7位随机数
其它信号函数 raise
4.信号的可靠与不可靠以及信号的含义
信号有丢失。(信号压缩)
由于历史的缘故:信号有压缩的需求。
可靠信号(实时信号)与不可靠信号(非实时信号)
早期信号 1-31 31个信号,不可靠(与系统有关)
后期信号34-64 31个信号,可靠信号(用户信号)
5.信号操作
信号导致的问题
1.信号屏蔽
intsigprocmask(int how, //操作方式 SIG_BLOCK, SIG_UNBLOC, SIG_SETMASK
constsigset_t *sigs, //操作的信号集合
sigset_t*oldsigs) //返回原来操作信号集合
1.声明信号结合
sigset_tsigs;
2.加入屏蔽信号
一组信号集合维护函数:
2.1清空集合 sigemptyset
2.2添加信号到集合 sigaddset
2.3从集合删除信号 sigdelset
2.4添加所有信号到集合 sigfillset
2.5判定信号是否在集合 sigismemeber
3.屏蔽信号
4.接触屏蔽
2.信号屏蔽的切换
intsigsuspend(sigset_t *sigs)
屏蔽新的信号,原来的信号失效。
sigsuspend是阻塞函数,对参数信号屏蔽。
对参数没有指定的信号不屏蔽,但当没有屏蔽信号处理完毕
sigsuspend返回条件:
1信号发生,并且信号是非屏蔽信号
2信号必须要处理,而且处理函数返回后,sigsuspend才返回
sigsuspend设置新的屏蔽信号,保存旧的屏蔽信号,而且当sigsuspend返回的时候,恢复旧的屏蔽信号。
3.查询被屏蔽的信号
intsigpending(sigset_t *sets);
当sigususpend没有屏蔽信号发生的时候,
回顾:
1.进程控制 sleeppasue
2.理解信号的中断流程
3.发射信号(shell /code), 处理信号
4.alarm与setitimer
5.信号应用:
实现简单多任务与进程之间通信
6.使用信号+sleep/pasue控制进程
7.信号的屏蔽
8.了解sigpending与sigsuspend的使用
作业:
1.写个程序,创建两个子进程,分别计算1-5000与 5001-10000之间的素数
通过信号让父进程专门去完成数据保存。
2.完成课堂上的作业:
显示7位随机数,同时使用定时器显示时间,
在使用键盘控制7位随机数的停止与继续显示。
(建议美化)
3.完成如下作业:
在屏幕上水平同时显示移动两个字符。
思考:
信号处理函数调用过程中,是否被其他信号影响。
明天:
1.信号与进程间数据传递
sigqueue===kill与sigaction==signal
2.IPC:
基于文件
无序文件:普通文件,映射
有序文件:1管道文件(有名/匿名管道)2 socket文件
基于内存
无序内存:内存共享
有序内存:共享队列