参考
https://www.cnblogs.com/zhanghongfeng/p/9108299.html
http://www.iteedu.com/os/linux/linuxprgm/linuxcfunctions/process/wait.php
https://blog.csdn.net/qq769651718/article/details/79393342
进程/信号 基础
-
信号:信号是一种软件中断,通过信号可以实现异步操作。Ctrl+c或delete都可以发送信号。
-
信号有若干种,接收到信号时有三种处理方式:忽略,默认,自定义函数。SIGKILL或SIGSTOP不能被忽略;大部分的信号默认操作都是终结进程。
-
void (*signal(int sig, void (*handler)(int)))(int);
接收一个信号;参数1是信号名,如SIGINT;参数2是处理方式,有三种: , ,或一个带int参数(信号编号)、无返回值的函数。分别对应忽略,默认,自定义。
PS:第一次碰到真正需要解析的声明。。
首先这是一个叫做 的函数,它的参数类型和返回值类型都是神仙。
先看参数,signal(int sig, void (*handler)(int))
,第一个参数叫 ,类型是 。
第二个参数叫 ,按 规则,它是一个指针;再按 规则,它是一个指向函数的指针。这个函数的参数是一个 ,返回值是 。
所以 的参数分别是一个 和一个函数指针,这是一个参数为 返回值为 的函数。
再看signal的返回值,void ( *signal )(int)
;
按 规则,它是一个指针,按 规则,它是一个指向函数的指针,这个函数的参数是一个 ,返回值是 。
所以, 函数接收一个 参数和一个函数指针参数,返回值也是一个函数指针参数,指向的函数都是 形式。
查阅文档得, 函数会将传入的函数指针再作为返回值返回。我猜可能是为了级联。
解析完成 -
int kill(pid_t pid,int sig)
,可以传递任意信号(不只是终结)。参数sig代表信号编号,pid有几种情况:- pid>0 将信号传给进程识别码为pid 的进程。
- pid=0 将信号传给和目前进程相同进程组的所有进程
- pid=-1 将信号广播传送给系统内所有的进程
- pid<0 将信号传给进程组识别码为pid绝对值的所有进程
-
pid_t wait (int * status);
暂停当前进程,直到收到信号或者子进程结束,子进程结束状态值会存储在status中,可以设为null。 -
pause()
,将进程挂起直到接收到一个信号 -
pid_t fork(void);
创建子进程,完全复制父进程各项数据。父进程中返回子进程的pid,子进程返回0. -
unsigned int alarm(unsigned int seconds);
经过seconds秒数后向进程发送一个SIGALARM信号,如果未设置这个信号的处理,则终止进程。
测试代码
# include <unistd.h>
# include <sys/wait.h>
# include<bits/stdc++.h>
int son1_pid, son2_pid, my_name;
void parent_handler(int)
{
kill(son1_pid, 16);
kill(son2_pid, 17);
wait(nullptr);
wait(nullptr);
printf("Parent process is killed!!\n");
exit(0);
}
void son_handler(int)
{
printf("Child process %d is killed by parent !!\n",my_name );
exit(0);
}
int create(int son_name, int sig_id)
{
int pid = fork();
if (pid == 0)
{
my_name = son_name;
signal(sig_id, son_handler);
signal(SIGINT, SIG_IGN);
while(1);
}
return pid;
}
int main()
{
son1_pid = create(1, 16);
son2_pid = create(2, 17);
signal(SIGINT, parent_handler);
while(1);
return 0;
}
管道 基础
- 管道是针对于本地计算机的两个进程之间的通信而设计的通信方法,管道建立后,实际上是获得两个文件描述符:一个用与读取而另一个用于写入。
- 任何从管道写入端写入的数据,可以从管道读取端读出。
- 管道是半双工的,数据只能向一个方向流动,需要双方通信时,要建立起两个管道。
- 管道存放在内存中,是一种独立的文件系统。
int pipe(int filedes[2]);
建立管道,filedes[0]为读端,filedes[1]为写端ssize_t write (int fd,const void * buf,size_t count);
把buf所指的内存写入count个字节到文件fd中,返回0表示成功ssize_t read(int fd,void * buf ,size_t count);
从fd所指的文件中读入count个字节到buf中,返回读入的字节数,最好将返回值与count比较
测试代码
#include <unistd.h>
#include <sys/wait.h>
#include <bits/stdc++.h>
void create(int son_name, int * pipedes)
{
pipe(pipedes);
int pid = fork();
if (pid == 0)
{
char info[50]={};
sprintf(info, "Child process %d is sending a message!", son_name);
write(pipedes[1], info, 50);
exit(0);
}
}
int main()
{
int pipedes1[2], pipedes2[2];
char info1[50], info2[50];
create(1, pipedes1);
create(2, pipedes2);
wait(nullptr); wait(nullptr);
read(pipedes1[0], info1, 50);
printf("%s\n", info1);
read(pipedes2[0], info2, 50);
printf("%s\n", info2);
return 0;
}