多进程
1.进程间的通信方式
套接字(socket ): 不同设备间
管道( pipe ):半双工,数据只能单向流动,父子进程间通信
有名管道 (namedpipe): 半双工的通信方式,允许无亲缘关系进程间的通信。
信号量(semophore ):信号量是一个计数器,多个进程对共享资源的访问。进程间以及同一进程内不同线程之间。
消息队列( messagequeue ) :
信号 (sinal ) :用于通知接收进程某个事件已经发生。
共享内存(shared memory ) : 一个进程创建,多个进程都可以访问。最快的 IPC 方式。与信号量配合使用。
2.僵尸进程
也就是进程描述符
fork出的子进程exit后成为僵尸进程,父进程使用wait或者waitpid回收子进程,父进程被杀后僵尸进程被init 1号进程接管并回收。
kill -9 无法杀死僵尸进程,
子进程退出时向父进程发送SIGCHILD信号,父进程处理SIGCHILD信号。在信号处理函数中调用wait进行处理僵尸进程。测试程序如下所示:
#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
signal(SIGCLD,SIG_IGN)
使用signal捕捉子进程产生的信号,默认不处理,SIG_IGN。子进程状态信息会被丢弃,也就是自动回收了,所以不会产生僵尸进程。
3.进程切换和线程切换区别
线程切换在同一个虚拟地址空间里,不会降低页表缓冲命中率。
进程切换在不同的虚拟地址空间中切换。
4.