linux进程间信号通信,Linux进程间通信之信号

一般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(),子进程不会变为僵死进程

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值