- 1、本文档共211页,可阅读全部内容。
- 2、有哪些信誉好的足球投注网站(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。
- 3、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载。
- 4、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
查看更多
《4-UNIXamp;Linux操作系统编程-线程同步和进程间通信》.ppt
整形信号量、记录型信号量 * 对于系统中的每个XSI IPC信号量,即每个信号量集,内核都会维护一个semid_ds的信息结构 * * * * * 举例子,引入信号。Ctrl C中断程序执行 * * 使用ctl+\发送sigkill信号,通过kill命令向a.out发送SIGKILL信号 使用ctrl+z发送sigstop信号 * * * * 详细解释signal的函数声明 * * * * * * * 竞争条件有可能发生在繁忙的系统上。若在alarm和pause发生进程切换,而且在切换回来前时钟到,产生了信号。在调用pause()后若无其他信号,则sleep1就有可能永远睡眠。 * * * 该程序引起另一个难于察觉的问题,它涉及到信号的相互作用。由于信号能相互嵌套,因此,如果SIGALRM信号中断了其他信号处理程序,则调用longjmp会提早中止该信号处理程序。反过来,当其他信号提前中断pause函数,从而导致程序继续执行,但后来的SIGALRM会导致longjmp回原来的位置。 * * * * * * * * * * * 可重入函数 每个线程只有一个errno。 当信号处理函数调用某个API后,errno可能被重新设置 这样,被信号中断的程序将看到被修改后的errno,而不是原来的值 所以,信号处理函数中,需要首先保存errno,在信号处理函数返回前,恢复errno * 线程安全的函数 对于同一个函数,若两个或两个以上的线程同时执行,均得到正确的结果,则称该函数是线程安全的函数 可重入的函数一定是线程安全的函数? 线程安全的函数,不一定是可重入的? 例如:互斥变量保护的临界区 例如malloc函数 * 信号集和可靠信号机制 基本概念 信号集及基本操作 sigprocmask函数,sigpending函数 sigaction函数 sigsuspend函数 可重入函数和线程安全的函数 信号 信号的概念 signal函数 不可靠信号与可靠信号 信号的发送接收机制 信号集与可靠信号机制 sigsetjmp和siglongjmp函数 abort函数 * sigsetjmp和siglongjmp函数 P57在分析sleep2时,使用到了setjmp和longjmp 在信号处理中,当捕捉到信号并进入信号处理函数时,当前信号被自动加入到进程的信号屏蔽字中 当退出信号处理函数时,当前信号又会从进程信号屏蔽字中删除 当使用longjmp跳出信号处理函数时,信号屏蔽字会有何改动?(示例5.21) * sigsetjmp和siglongjmp函数 从示例5.21可知,longjmp并未恢复进程的信号屏蔽字 POSIX.1定义了sigsetjmp和siglongjmp,以解决上述问题。 调用sigsetjmp时,除了保存上下文外,还将保存当前的信号屏蔽字 调用siglongjmp执行跳转后,将恢复调用sigsetjmp时的信号屏蔽字 * sigsetjmp和siglongjmp函数 函数原型 #includesetjmp.h int sigsetjmp(sigjmp_buf env, int savemask); 参数和返回值 若savemask非0,则sigsetjmp在env中保存进程的当前信号屏蔽字 返回值:若直接调用则返回0,若从siglongjmp调用返回则返回siglongjmp的第二个参数 * sigsetjmp和siglongjmp函数 函数原型 #includesetjmp.h void siglongjmp(sigjmp_buf env, int val); 参数 val作为sigsetjmp的返回值 * static void sig_usr1(int), sig_alrm(int); static sigjmp_buf jmpbuf; static volatile sig_atomic_t canjump; int main(void) { if (signal(SIGUSR1, sig_usr1) == SIG_ERR) err_sys(signal(SIGUSR1) error); if (signal(SIGALRM, sig_alrm) == SIG_ERR) err_sys(signal(SIGALRM) error); pr_mask(starting main: ); /* {Prog prmask} 10.10*/ if (sigsetjmp(jmpb
文档评论(0)