Linux进程间通信---信号

信号

对于 Linux来说,实际信号是软中断,许多重要的程序都需要处理信号。信号,为 Linux 提供了一种处理异步事件的方法。比如,终端用户输入了 ctrl+c 来中断程序,会通过信号机制停止一个程序。信号是进程间通信唯一的异步方式,是对中断的一种软件模拟(发送一个信号到这个进程去,我另一个进程铺捉到这个信号,来执行其他东西)

信号:分为3种模式,捕捉,忽略,系统默认

signalkillsigactionsigqueue

kill -l 查看所有信号

kill -p pid 终止这个进程

signal注册信号

typedef void (*sighandler_t)(int);//这是typedef定义的函数指针,也就是sighandler具有函数指针的类型,可以sighandler p,这样在定义一个函数指针

sighandler_t signal(int signum, sighandler_t handler);//所以signal的返回类型是void*

brief:注册信号,也可以理解成我把接收到的信号,用于捕捉,忽略,还是等等

param:signum,即处理的信号,handler,我接收到signum这个信号用来进行其他事情

return:

kill给进程发送指定信号

int kill(pid_t pid, int sig);

brief:发送一个信号给这个pid

param:pid,即注册信号的pid,sig,执行信号的命令

return:成功返回0,失败返回-1

#include <signal.h>
#include <stdio.h>
​
void handler()
{
​
        printf("error\n");
​
}
​
​
void main()
{
        printf("pid = %d\n",getpid());
​
        signal(2,handler);
​
        while(1);
​
}
--------------------------------------------------------------------------------------------------------------------------------
#include <signal.h>
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <stdlib.h>
​
void main(int argc,char **argv)
{
        if(argc != 3)
        {
                printf("error");
                exit(-1);
        }
​
        int pid;
        int signum;
​
        pid =atoi( argv[2]);//将字符型转换成int型
        signum = atoi(argv[1]);
​
        kill(pid,signum);
​
​
}

sigaction注册信号

int sigaction(int signum, const struct sigaction *act, struct sigaction *oldact);

struct sigaction {
   void       (*sa_handler)(int); //信号处理程序,不接受额外数据,SIG_IGN 为忽略,SIG_DFL 为默认动作
   void       (*sa_sigaction)(int, siginfo_t *, void *); //信号处理程序,能够接受额外数据和sigqueue配合使用
   sigset_t   sa_mask;//阻塞关键字的信号集,可以再调用捕捉函数之前,把信号添加到信号阻塞字,信号捕捉函数返回之前恢复为原先的值。
   int        sa_flags;//影响信号的行为SA_SIGINFO表示能够接受数据
 };

struct sigaction {

void (sa_handler)(int);//跟signal处理函数一样,不能携带消息 ​ void (sa_sigaction)(int, siginfo_t *, void );//处理函数,且可以携带消息

}

            补充一下siginfo结构体:
            siginfo_t {
              int      si_signo;  /* Signal number */
              int      si_errno;  /* An errno value */
              int      si_code;   /* Signal code */
              pid_t    si_pid;    /* Sending process ID */
              uid_t    si_uid;    /* Real user ID of sending process */
              int      si_status; /* Exit value or signal */
              clock_t  si_utime;  /* User time consumed */
              clock_t  si_stime;  /* System time consumed */
              sigval_t si_value;  /* Signal value */ 
              int      si_int;    /* POSIX.1b signal */
              void *   si_ptr;    /* POSIX.1b signal */
              void *   si_addr;   /* Memory location which caused fault */
              int      si_band;   /* Band event */
              int      si_fd;     /* File descriptor */
          }

brief:接收信号,且接收数据

param:signum,要处理的信号,act,是一个结构体指针,用于接收到这个消息来干嘛,oldact,备份

return:

sigqueue发送指定信号(和数据)

int sigqueue(pid_t pid, int sig, const union sigval value);

union sigval {

       int   sival_int;//整型数据
       void *sival_ptr;//字符数据

};

brief:用于发送指定信号给id,和数据

param:pid,需要发送信号的id,sig,要发送的信号,value,需要发送的数据,这个数据存在联合体

return:成功返回0,失败返回-1

#include <signal.h>
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <stdlib.h>
​
​
void handler(int signum,siginfo_t * info,void *ucontext)
{
        printf("signum: %d\n",signum);
​
        if(ucontext != NULL)//不等于NULL才有数据
        {
                printf("get data:%d",info ->si_int);//si_int和si_value.sival_int是一样的--针对额外数据是int的时候。
​
​
        }
​
}
​
​
​
void main()
{
        printf("pid : %d\n",getpid());
​
        struct sigaction act;
        act.sa_sigaction = handler;
        act.sa_flags = SA_SIGINFO;//接受数据
​
        sigaction(10,&act,NULL);// SIGUSR1,用户自定义信号
​
        while(1);
​
}
--------------------------------------------------------------------------------------------------------------------------------
#include <signal.h>
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <stdlib.h>
​
​
void main(int argc,char ** argv )
{
        if(argc != 3)
        {
                printf("error");
                exit(-1);
        }
​
        int pid;
        int signum;
​
        union sigval value;
        value.sival_int = 666;
                
        pid = atoi(argv[2]);
        signum = atoi(argv[1]);
​
        sigqueue(pid,signum,value);
​
}

sprintf实现kill指令

#include <signal.h>
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
​
void main(int argc,char **argv )
{
        int pid;
        int signum;
​
        char cmd[128];
​
        pid = atoi(argv[2]);//atoi show char zhuanhuan int
        signum = atoi(argv[1]);
​
        sprintf(cmd,"kill -%d %d",signum,pid);//把数据打印到字符串上去
​
​
        system(cmd);
​
}
​

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

No Iverson

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值