最近在写一个驱动测试程序的时候想用一下进程间通信的功能,可是就是想不起来应该怎么写,所以重新拿起《linux程序设计》再学一遍,然后用半天的时间,写一个简单的笔迹,以备后用。
一、进程
使进程同时执行多个函数的方法有:一、使用多线程;二、原程序中创建一个分离进程
本文主要关注的是进程间的通信,所以下面的内容介绍的是分离进程的做法。
1.复制进程映像
#include<sys/types.h>
#include<unistd>
Pid_t fork(void);
子进程中fork调用返回的是0,如果fork失败返回-1。
2.等待进程
在对复制进程映像作示例前还要特别注意一个现象就是僵尸进程(zombie),处理这种现象的函数:
#include<sys/types.h>
#include<sys/wait.h>
Pid_twait(int *stat_loc);
Pid_twaitpid(pid_t pid, int *stat_loc, int options);
Wait系统调用将暂停父进程直到他的子进程结束为止;waitpid用来等待某个特定进程的结束;
通过读取*stat_loc得到的错误状态信息:
#include <sys/wait.h>中定义了这些宏。
WIFEXITED(stat_val) :如果子进程正常结束,它就取一个非0;
WEXITSTATUS(stat_val) :如果WIFEXITED(stat_val)非0,它返回子进程的退出码;
WIFSIGNALED(stat_val) :如果子进程因为一个未捕获的信号而终止,他就取一个非0;
WTERMSIG(stat_val) :如果 WIFSIGNALED(stat_val)非0,他返回一个信号代码;
WIFSTOPPED(stat_val) :如果子进程意外终止,他就取一个非0;
WSTOPSIG(stat_val) :如果WIFSTOPPED非0,他返回一个信号代码;
僵尸进程:子进程结束了,其依旧会在进程表中,不会立即释放,知道其父进程结束为止。因为他的退出码还需要被别的进程所使用到,以备父进程wait调用。这时他就是一个僵尸进程
例程:
#include<stdio.h>
#include<stdlib.h>
#include<sys/types.h>
#include<sys/wait.h>
intmain (){
int res;
res = fork();
switch(res){
case 0:
sleep(5);
printf("process ischild\n");
printf("process:%d\n",res);
break;
case -1:
printf("fork is fail\n");
break;
default:
sleep(1);
printf("this isparent\n");
printf("process:%d\n",res);
break;
}
printf("process is finish\n");
if (res != 0){
wait((void*)0);
// waitpid(0,(void*)0, WNOHANG);
}
return 0;
}
3.信号
信号:是unix/linux系统响应某些条件而产生的一个事件。
信号还可以作为进程间传递消息或修改行为的一种方式。接收到信号的进程会相应的采取一些行动。信号是由某些错误条件而生成的:如内存段冲突,浮点处理错误,非法指令等。
#include <signal.h>
常见的:sigint sigquit sigabort sigalrm sigill sigterm
如果接收到信号中的一个,但事先没有捕获他,进程将会立即终止。
程序中使用:signal() 库函数来处理信号。
#include <signal.h>
signal(SIGINT,SIG_DFL);
发送信号:
调用kill() 函数向其他进程包括自己发送信号。
#include <sys/types.h>
#include <signal.h>
int kill ( pid_t pid , int sig );
闹钟的函数:
alarm() 在经过预定时间后发送一个sigalrm信号,seconds秒后发送一条sigalrm信号,将seconds设置为0,将取消所有已经设置的闹钟请求:
#include <unistd.h>
unsigned int alarm(unisgned intseconds);
挂起一个进程的函数:
把程序执行挂起直到一个信号出现为止。
#include <unistd.h>
int pause(void) ;
还有信号集的部分见《linux程序设计(第三版)》11.4.3信号集:403页