13 多进程编程

13.1 fork系统调用

1 #include <syus/types.h>
2 #include <unistd.h>
3 pid_t fork( void )

该函数每次调用返回两次,父进程返回子进程的PID,子进程返回0

子进程的代码和父进程完全相同,同时它还会复制父进程的数据(堆栈数据和静态数据),数据的复制采用写时复制(copy on write)

父进程打开的文件描述符在子进程中也打开,且文件描述符引用计数加1。且父进程的用户根目录、当前工作目录等变量的引用计数均会加1

 

13.2 exec系列系统调用

在子进程中执行其他程序,即替换当前进程映像

1 #include <unistd.h>
2 extern char** environ;
3 
4 int execl(const char* path, const char* arg, ...);
5 int execlp(const char* file, const char* arg, ...);
6 int execle(const char* path, const char* arg, ..., char* const envp[]);
7 int execv(const char* path, char* const argv[]);
8 int execvp(const char* file, char* const argv[]);
9 int execve(const char* path, char* const argv[], char* const envp[]);

 

13.3 处理僵尸进程

僵尸进程两种情况:

1. 子进程结束之后,父进程读取其状态之前,称该进程为僵尸进程

2. 父进程异常结束或终止,而子进程继续运行,自己称被init进程接管

子进程在僵尸状态占据内核资源,下面这对函数在父进程中调用,以等待子进程的结束,并获取子进程的返回信息,从而避免僵尸进程的产生,或者使子进程的僵尸状态立即结束

1 #include <sys/types.h>
2 #include <sys/wait.h>
3 pid_t wait(int* stat_loc);//将阻塞进程
4 pid_t waitpid(pid_t pid, int* stat_loc, int options);//可以设置WNOHANG参数

 wait函数阻塞进程,直到该进程的某个子进程结束运行为止,返回子进程的PID。

 

13.4 管道

父子进程通信的常用手段,父子进程必须有一个关闭fd[0],一个关闭fd[1]

双向传输需要两个管道。socket编程接口提供了一个创建全双工的管道的系统调用socketpair。

 

13.5 信号量

Linux信号量的API都定义在sys/sem.h头文件中

semget系统调用:创建一个新的信号量集
int semget(key_t key, int num_sems, int sem_flags);
semop系统调用:改变信号量的值,即PV操作
1 int semop(int sem_id, struct sembuf* sem_ops, size_t num_sem_ops);
semctl系统调用:允许调用者对信号量进行直接控制
1 int semctl(int sem_id, int sem_num, int command, ...);
 
13.6 共享内存

共享内存是最高效的IPC机制,因为它不涉及任何进程之间的数据传输。

共享内存的API都定义在sys/shm.h头文件中

shmget系统调用:创建一段新的共享内存,或者获取一段已经存在的共享内存

int shmget(key_t key, size_t size, int shmflg);

shmat和shmdt系统调用:创建完共享内存需要将它关联到进程的地址空间,用完后需要将它从地址空间中分离

void* shmat(int shm_id, const void* shm_addr, int shmflg);
int shmdt(const void* shm_addr);

shmctl系统调用:用于控制共享内存的某些属性

int shmctl(int shm_id, int command, struct shmid_ds* buf);

共享内存的posix方法:

Posix共享内存区涉及以下两个步骤要求:

(1)指定一个名字参数调用shm_open,以创建一个新的共享内存区对象或打开一个已经存在的共享内存区对象。

(2)调用mmap把这个共享内存区映射到调用进程的地址空间。

注意:mmap用于把一个内存区对象映射到调用进程地址空间的是该对象的一个已经打开描述符。

http://www.cnblogs.com/Anker/archive/2013/01/19/2867696.html

 
13.7 消息队列
msgget系统调用:创建一个消息队列,或者获取一个已有的消息队列
int msgget(key_t key, int msgflg);

msgsnd系统调用:把一条消息添加到消息队列中

int msgsnd(int msgqid, const void* msg_ptr, size_t msg_sz, int msgflg);

msgrcv系统调用:从消息队列中获取信息

int msgrcv(int msqid, void* msg_ptr, size_t msg_sz, long int msgtype, int msgflg);

msgctl系统调用:控制消息队列的某些属性

int msgctl(int msqid, int command, struct msqid_ds* buf);

 

posted on 2015-12-11 15:17  已停更  阅读(351)  评论(0编辑  收藏  举报