一般Linux进程间通信的方法有这些:
管道(Pipe):数据只能单向流动,而且只能在具有亲缘关系的进程间使用。进程的亲缘关系通常是指父子进程关系
无名管道(Named pipe):数据只能单向流动,但是可以在非亲缘关系的进程中通信
信号(Signal):用于通知接收进程某个事件已经发生
信号量(Semophore):信号量是一个计数器,可以用来控制多个进程对共享资源的访问。它常作为一种锁机制,防止某进程正在访问共享资源时,其他进程也访问该资源。因此,主 要作为进程间以及同一进程内不同线程之间的同步手段
消息队列(Message queue):消息队列是由消息的链表,存放在内核中并由消息队列标识符标识。消息队列克服了信号传递信息少、管道只能承载无格式字节流以及缓冲区大小受 限等缺点。
Socket:套解口也是一种进程间通信机制,与其他通信机制不同的是,它可用于不同机器间的进程通信
共享内存(Share memory):共享内存就是映射一段能被其他进程所访问的内存,这段共享内存由一个进程创建,但多个进程都可以访问。共享内存是最快的 IPC 方式,它是针对其 他进程间通信方式运行效率低而专门设计的。它往往与其他通信机制,如信号量,配合使用,来实现进程间的同步和通信。
注:信号和信号量是两码事!!!
信号(signal)的使用实例:
#include
#include
#include
#include
#include
pid_t p1;//声明进程号
int result;
void signal_handle_fun(int sign_no);
void signal_handle_fun_2(int sign_no);
int main()
{
p1 = fork();//复制一个子进程
if(p1 == 0)//当fork()返回值为0时,此时是子进程
{
//定义一个信号处理函数,处理SIGINT信号 处理函数为signal_handle_fun_2
signal(SIGINT,signal_handle_fun_2);
printf("Child Progress is build!!! pid =%d\n",getpid());
//sleep(2);
pause();//将进程挂起休眠直到捕捉到信号为止
printf("Child Progress has receiver Signal and wack up !!!\n");
exit(0);//正常结束进程
}else if(p1 > 0)
{
printf("Main Progress is build!!! pid =%d\n",getpid());
sleep(2);
//定义一个信号处理函数,处理SIGINT信号 处理函数为signal_handle_fun
signal(SIGINT,signal_handle_fun);
//定义一个信号处理函数,处理SIGABRT信号 处理函数为signal_handle_fun
signal(SIGABRT,signal_handle_fun);
raise(SIGABRT);//给调用raise的进程发送SIGABRT信号
kill(0,SIGINT);//将信号SIGINT发送给同一进程组的所有进程
pause();//将进程挂起休眠直到捕捉到信号为止
pause();
sleep(5);
result = wait(NULL);//等待子进程退出。NULL的意思是退出状态不关注
printf("wait result =%d\n",result);
exit(0);
}
return 0;
}
void signal_handle_fun_2(int sign_no)
{
if(sign_no == SIGINT)
{
printf("---22222222--->handle the SIGINT\n");
}
}
void signal_handle_fun(int sign_no)
{
if(sign_no == SIGINT)
{
printf("------>handle the SIGINT\n");
}else if(sign_no == SIGABRT){
printf("------>handle the SIGABRT\n");
}
}
几个常用函数:
fork();
复制一个子进程,且子进程继承父进程的数据段,堆栈段(不与父进程共享);
并且fork()函数调用一次 返回2个值,返回值>0的时候,表示在父进程中.返回值=0的时候,表示在子进程中.返回值<0的时候 出现错误
拓展:fork()与vfork()区别:
vfork()子进程与父进程共享数据段
fork()父子进程执行次序不确定,vfork()保证子进程先执行
signal(int signum,sighandler_t handler);
定义一个信号处理函数,处理signum信号 处理函数为handler
注意,这里只是定义,不是发送signum信号
pause();
将进程挂起休眠直到捕捉到信号为止
exit(int status);
参数为0的时候,表示正常结束进程,参数为-1的时候,表示强制结束进程
raise(int sig);
只给当前进程发送信号
kill(pid_t pid,int sig);
pid为0的时候,表示发送sig信号给所有和当前进程在同一进程组的进程
pid为正数的时候,表示发给pid进程号
pid = -1,表示给所有进程表中的进程发送sig信号
alarm(unsiged int seconds);
也称为闹钟函数,可以在进程中设置一个定时器.当seconds到达时间的时候,会向当前进程发送SIGALRM信号
wait(int *status);
若子进程先于父进程结束时,父进程没有调用wait()/waitpid()函数,子进程就会进入僵死状态;
若父进程调用了wait()/waitpid(),子进程不会变为僵死进程