《Linux高性能服务器编程》——多进程编程

阅读《Linux高性能服务器》的笔记

一 API

  1. fork系统调用

    #include <sys/types.h>
    #include <unistd.h>
    pid_t fork(void);
    /*
    	返回值:
    				0,表示当前在子进程
    				>0,子进程ID,表示当前在父进程
    				-1:失败,设置errno
    */
    
    • 子进程代码与父进程相同。
    • 写时复制(堆数据、栈数据、静态数据)。先是缺页中断,然后操作系统给子进程分配内存并复制父进程数据。
    • 创建子进程后,父进程中打开的文件描述符默认在子进程中也是打开的。
  2. exec系列系统调用

在这里插入图片描述

  • 参数
    • path:可执行文件的完整路径
    • file:文件名,具体位置在环境变量PATH中搜索
    • arg:可变参数
    • argv:参数数组,都会传递给新程序的main函数
    • envp:设置新程序的环境变量,不设置就用全局变量environ
  • 返回值
    • 成功,不返回,直接新程序
    • 失败,返回-1,设置errno
  • exec函数不会关闭原程序打开的文件描述符,除非该文件描述符设置了SOCK_CLOEXEC

二 处理僵尸进程

  1. 僵尸态

    • 在子进程运行结束后,父进程读取其退出状态之前,该子进程处于僵尸态。
    • 父进程结束或异常终止,子进程继续运行。此时子进程的PPID设置为1(init进程)
  2. API

    #include <sys/types.h>
    #include <sys/wait.h>
    pid_t wait(int* stat_loc);
    /*
    	阻塞进程,直到该进程的某个子进程结束运行为止。
    	stat_loc:保存结束运行的子进程的退出状态
    	返回值:结束运行的子进程的PID
    */
    
    pid_t waitpid(pid_t pid, int* stat_loc, int options)
    /*
    	只等待pid进程
    	pid:
    			-1,和wait相同
    			>0,指定子进程
    	stat_loc:与wait的相同
    	options:
    			WNOHANG:非阻塞,pid指定的子进程没结束或意外结束,返回0
    							子正常退出,返回子进程PID
    							调用失败,返回-1,设置errno
    */
    
    

在这里插入图片描述

  1. SIGCHILD信号的典型处理函数
    • 对waitpid而言,最好在某个进程退出后再调用。

    • 通过SIGHUP信号,父进程能够直到子进程退出了。

      static void handle_child(int sig)
      {
      	pid_t pid;
      	int stat;
      	while((pid = waitpid(-1, &stat, WNOHANG)) > 0))
      	{
      		//对结束的子进程进行善后处理
      	}
      }
      

三 管道

  1. 概念
    • 进程间通信(父子进程等有关联的两个进程)
    • 父子进程间传递数据。
      • 父进程和子进程必须右一个关闭fd[0],另一个关闭fd[1]

在这里插入图片描述

- 父子进程实现双向数据传输,需要两个管道
- socketpair(),创建一个全双工管道

四 信号量

  1. 概念
    • 对于公共资源,只能一个进程访问
    • PV操作
      • 信号量SV
      • P操作,SV>0,SV—;SV==0,挂起进程
      • V操作,有进程等待,唤醒;无等待,SV++

在这里插入图片描述

  1. semget系统调用
    • API

      #include <sys/sem.h>
      int semget(key_t key, int num_sems, int sem_flags);
      /*
      	获取或创建信号量集
      	key:标识全局唯一的信号集。
      	num_sems:创建/获取的新信号量数量。
      						创建:必须指定
      						获取:0
      	sem_flags:信号量权限,和open的mode参数相同
      	返回值:
      				>0,信号量标识符
      				-1,失败,设置errno
      */
      

在这里插入图片描述

  1. semop系统调用

    • 改变信号量的值,即执行P、V操作
  2. semctl系统调用

    • 允许调用者对信号量进行直接控制

五 共享内存

  1. 概念

    • 最高效的IPC机制,不涉及进程间任何数据传输。
    • 必须使用其他辅助手段同步进程对共享内存的访问。
  2. shmget系统调用

    #include <sys/shm.h>
    int shmget(ket_t key, size_t size, int shmflg);
    /*
    	key:标识全局唯一的共享内存
    	size:共享内存的大小。
    				创建:必须指定
    				获取:0
    	shmflg:共享内存权限
    	返回值:
    				>0,共享内存标识符
    				-1,失败,设置errno
    */
    
  3. shmat和shmdt系统调用

    #include <sys/shm.h>
    void* shmat(int shm_id, const void* shm_addr, int shmflg);
    /*
    	关联共享内存到地址空间
    	shm_id:shmget的返回值
    	shm_addr:指定将共享内存关联到进程的哪块位置,一般为NULL,系统自己分配
    	shmflg:
    				SHM_RDONLY。进程只能读取共享内存的内容。没指定,默认可以读写(必须在创建共享内存的时候指定其读写权限)
    	返回值:
    				失败:(void*)-1,设置errno
    				成功:共享内存被关联到的地址
    */
    
    int shmdt(const void* shm_addr);
    /*
    	分离
    	shm_addr:shmat的返回值
    */
    
  4. shmctl系统调用

    #include <sys/shm.h>
    int shmctl(int shm_id, int command, struct shmid_ds* buf);
    /*
    	shm_id:shmget的返回值
    	command:
    				IPC_RMID:在共享内存打上删除的标记,当最后一个进程调用shmdt时,该共享内存就删除了
    */
    
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值