多进程
1.进程间的通信方式
套接字(socket ): 不同设备间
管道( pipe ):半双工,数据只能单向流动,父子进程间通信
有名管道 (namedpipe): 半双工的通信方式,允许无亲缘关系进程间的通信。
信号量(semophore ):信号量是一个计数器,多个进程对共享资源的访问。进程间以及同一进程内不同线程之间。
消息队列( messagequeue ) :
信号 (sinal ) :用于通知接收进程某个事件已经发生。
共享内存(shared memory ) : 一个进程创建,多个进程都可以访问。最快的 IPC 方式。与信号量配合使用。
2.僵尸进程
也就是进程描述符
fork出的子进程exit后成为僵尸进程,父进程使用wait或者waitpid回收子进程,父进程被杀后僵尸进程被init 1号进程接管并回收。
kill -9 无法杀死僵尸进程,
子进程退出时向父进程发送SIGCHILD信号,父进程处理SIGCHILD信号。在信号处理函数中调用wait进行处理僵尸进程。测试程序如下所示:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 | #include <stdio.h> #include <unistd.h> #include <errno.h> #include <stdlib.h> #include <signal.h> static void sig_child( int signo); int main() { pid_t pid; //创建捕捉子进程退出信号 signal (SIGCHLD,sig_child); pid = fork(); if (pid < 0) { perror ( "fork error:" ); exit (1); } else if (pid == 0) { printf ( "I am child process,pid id %d.I am exiting.\n" ,getpid()); exit (0); } printf ( "I am father process.I will sleep two seconds\n" ); //等待子进程先退出 sleep(2); //输出进程信息 system ( "ps -o pid,ppid,state,tty,command" ); printf ( "father process is exiting.\n" ); return 0; } static void sig_child( int signo) { pid_t pid; int stat; //处理僵尸进程 while ((pid = waitpid(-1, &stat, WNOHANG)) >0) printf ( "child %d terminated.\n" , pid); } |
默认的处理是SIG_IGN
1 | signal (SIGCLD,SIG_IGN) |
使用signal捕捉子进程产生的信号,默认不处理,SIG_IGN。子进程状态信息会被丢弃,也就是自动回收了,所以不会产生僵尸进程。
3.进程切换和线程切换区别
线程切换在同一个虚拟地址空间里,不会降低页表缓冲命中率。
进程切换在不同的虚拟地址空间中切换。
4.
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 25岁的心里话
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现