Linux系统编程(3)

1. mmap的注意事项

如果要做操作,需要单独创建一个变量来操作,最后munmap函数传入的仍然是ptr。

 

  

2. 使用mmap进行有血缘关系的进程间通信

例:父进程往映射区写一句话,这句话被同步到磁盘文件,子进程中映射区同步了磁盘文件的内容,然后将映射区的内容打印出来。

注:内存映射区是非阻塞的,所以上面的程序不能保证父进程先写进去,然后子进程再读出来,我们应该在子进程中加上sleep,以确保父进程完成操作。

3. 创建匿名映射区

创建匿名映射区就不用打开文件了,但需要指定匿名映射区的大小,然后将标志位加上MAP_ANON,文件描述符的位置写为-1。

例:

4. mmap没有血缘关系的进程间通信

例:进程a和进程b进行通信,a读b写。先运行a时没有输出,因为内存映射区中无内容,然后运行b,这时a就会输出内容了。

进程a:

进程b:

5. 信号的介绍

常用信号:

6. 阻塞信号集和未决信号集的概念

阻塞信号集和未决信号集在pcb中,所以不能直接操作。

7. kill函数的使用

例:在子进程中调用kill函数杀死父进程。

执行结果:

8. raise和abort函数

(1)raise函数

例:子进程给自己发信号自杀,父进程回收子进程,并打印子进程是被哪个信号杀死的。

执行结果:

(2)abort函数

例:子进程给自己发送异常终止信号,父进程回收子进程,并打印子进程是被哪个信号杀死的。

执行结果:

9. alarm函数

第一次调用alarm函数,返回0。然后再调用alarm函数重置定时时间时,返回的是重置操作之前还剩余多少秒。

例:

执行结果:

10. 计算1s数多少个数

(1)输出到终端:

用time命令查看程序运行用时:

执行结果:

可以看到实际上数数用的时间只有0.06秒。

(2)输出到文件

可以看到输出到文件后,有0.728秒用于数数,打开文件可以看到数到了600多万。

分析原因:

输出到终端时,要频繁地进行用户区到内核区的切换,所以损耗很高;而输出到文件时,切换的次数就少很多了,所以损耗低。

11. setitimer定时器函数的使用

其中参数which是定时法则,当设置为ITIMER_REAL时,是自然定时法,时间到了后发出信号SIGALRM;当设置为ITIMER_VIRTUAL时,是只算用户区的时间,时间到了后发出信号SIGVTALRM;当设置为ITIMER_PROF时,是只算用户+损耗的时间,时间到了后发出信号SIGPROF。

参数new_value是设置时间的。最后一个参数一般不用,设置为NULL即可。

例:

执行结果:

 

12. 阻塞信号集和未决信号集的状态关系

如果要设置阻塞信号集,那么我们要先创建一个自定义信号集,想要阻塞哪个信号,就把哪个信号对应位置的标志位设为1。将自定义信号集的各个标志位都设置好了之后,然后通过一系列的信号集操作函数,把这个自定义信号集设置给阻塞信号集。

13. 读当前进程的未决信号集

注:sigprocmask函数的how参数取值如下,其中取SIG_BLOCK最常用。oldset参数是传出参数,如不感兴趣设为NULL。

例:读取当前进程的未决信号集

执行结果:

14. 设置信号阻塞

设置SIGINT信号、SIGQUIT信号阻塞,并试图设置SIGKILL信号阻塞(该信号是不能被阻塞的,设置了也没用)。

 

执行结果:一开始都是0,按ctrl+c后,第二位变为1,按ctrl+反斜杠后,第三位变为1。

可以看到第9位是0,所以9号信号是不能被阻塞的。当我们用kill -9杀死该进程后,发现果然被杀死了。

15. signal信号捕捉函数

例:

每当按下ctrl+c时,signal函数会捕捉信号SIGINT,回调myfunc函数。no传入的是信号的编号。

执行结果:

16. sigaction函数的使用

       

注:结构体sigaction中,用第一个函数指针,不用第二个。如果在信号处理函数执行过程中,不临时屏蔽信号,那么将sa_mask信号集重置;如果需要临时屏蔽指定的信号,那么用sigaddset函数设置sa_mask信号集,这样在信号处理函数执行过程中,就会临时屏蔽指定的信号,当信号处理函数执行结束后,进程会处理该信号。sa_flags固定设置为0。

例1:没有临时屏蔽的信号

执行结果:

例2:临时屏蔽信号SIGQUIT

执行结果:

解释:当按下ctrl+c时,sigaction函数会捕捉信号SIGINT,回调myfunc函数,在myfunc函数中,先打印helloword,然后睡3秒,在睡觉期间按ctrl+反斜杠不会立即退出,这是因为已经设置了在回调函数执行过程中临时屏蔽SIGQUIT信号。睡醒后打印wakeup,然后回调函数结束,此时进程才会处理该信号,于是进程退出。

猜你喜欢

转载自blog.csdn.net/mengyujia1234/article/details/91040133