守护进程
特点:后台执行,和终端无关;系统启动时运行,系统关闭是停止运行
实现守护进程需要满足的点:守护进程不能和终端有“血缘关系”;守护进程没有控制终端
实现的效果:守护进程自成一组,会话组和进程组的组长都是守护进程自己。
守护进程的父进程只能是systemd。
没有控制终端(也就是TTY是?)
守护进程编写步骤
步骤:创建子进程,父进程退出(作用:实现从形式上脱离终端)
在子进程中创建新会话(调用setsid函数)
改变当前目录为根目录(调用chdir函数)
重设文件权限掩码(调用umask函数)
关闭文件描述符(在创建完新的会话后,守护进程已经脱离任何控制终端,应当关闭用不到的文件)
注意:操作系统提供的了创建守护进程的函数daemon。
故可以自己写,也可以调用系统的函数
进程间通信
基础概念:
单工、半双工、全双工;同步、异步;通信协议
无名管道
特点:只能用于亲缘关系的进程之间的通信;半双工
创建:pipe()、关闭:close(fd[0])、close(fd[1])
注意:当管道中无数据时,读操作会阻塞。
向管道写入数据时,linux不保证完整输入,写进程在管道写入数据,如果管道里的数据满,那么写进程会一直阻塞
只有在管道的读端存在时,向管道中写入数据才有意义
有名管道
基础:可以使互不相关的两个进程相互通信;
有名管道可以通过路径名来指出,并且在文件系统中可见;
进程通过文件IO来操作有名管道(遵循先进先出规则);
创建:mkfifo()、打开:open()(打开管道文件)、关闭:close()
信号
概念:信号是在软件层次上对中断机制的一种模拟,是一种异步通信方式。
用户进程对信号的响应方式:忽略信号(对SIGKILL、SIGSTOP不能被忽略)
捕捉信号(执行相应的处理函数)
执行默认操作
信号函数
发送:kill()(可以发送信号给进程或进程组)、raise()(给正在执行的程序发送一个信号)
处理:signal()(也称安装信号函数或者注册信号函数,可以指定调用进程收到signum这个信号的处理方式)
闹钟函数:alarm()(当指定的时间到时,内核就向进程发送SIGALARM信号)
挂起函数:pause()(用于将调用进程挂起直到收到信号为止)
共享内存
概念:是一种最为高效的进程间通信方式,进程可以直接读写内存,不需要任何数据的拷贝
管道与共享内存的比较:
管道:写管道的进程将自己用户空间的buf的内容通过write函数拷贝一份到内核空间中
读管道的进程将内核空间的内容通过read函数拷贝到了用户空间的buf
共享内存:
步骤: 创建/打开共享内存
shmget()(存在时得到一个共享内存标识符或者没有时创建一个共享内存对象并 返回共享内存表示符)
ftok()(系统建立IPC通信必须指定一个ID值,该ID值通过ftok函数得到)
映射共享内存
shmat()(把指定的共享内存映射到进程的地址空间用于访问)
访问共享内存
撤销共享内存
shmdt()(与shmat函数相反,是用来断开与共享内存附加点的地址,禁止本进程访问此片共享内存)
删除共享内存对象
shmctl()(共享内存管理,完成对共享内存的控制)
谁最后一次操作共享内存,谁进行删除
消息队列
概念:是一个消息的列表。用户可以在消息队列中添加下消息、读取消息等
特点:可按照类型来发送/接受消息
步骤:发送方:创建并打开消息队列、添加消息。
接收方:创建并打开消息队列、按照类型读消息、删除消息队列
函数:msgsnd()