讲师博文
对Llinux下signal机制的一点认识 来源 : 未知     2018-09-20

Linux中的signal是一种异步处通信机制,信号类型分为可靠信号和非可靠信号两种。所谓非可靠信号是linux继承unix的编号从1至31号信号,是用作特殊用处;可靠信号即linux中新添加的编号从34至64的信号,此类信号可以用户自定义使用。

由于linux的signal机制也经过了一系列的改造,因此我们就拿现在的signal机制来分析一下signal的使用。

一、信号的发送

信号的产生方式有多种,可能是用户程序使用相关函数进行发送,也可能是用户通过外部输入通知内核来产生信号等等。我们就那用户程序来说明一下用户空间信号的发送。

1)进程中:

int kill(pid_t pid, int sig);

int raise(int sig);

kill函数来给对应的进程发送信号。其中pid参数有三种类型:

pid 大于0时,就是给PID为pid的进程发送sig信号。

Pid 等于0时, 就是给和当前进程在同一进程组的所有进程发送sig信号。

Pid 等于-1时,会给所有有权限发送的进程发送sig信号,除了init进程。

父进程杀死子进程的示例代码:

Pid = fork();

If (pid == 0)

{

Printf(“in the child process\n”);

While (1);

}

else if (pid > 0)

{

Printf(“in the parent process\n”);

Kill(getpid(), SIGKILL);

Wait(NULL);

}

return 0;

raise函数就是进程给自己发送信号。

比如: raise(SIGKILL);就是进程的自杀信号。

2)线程的信号发送

int pthread_kill(pthread_t thread, int sig);

参数pthread_t就是指定要发送的线程标识符,sig就是要送的信号。

如果给线程发送的信号的默认处理方式是终止进程,那么也会导致进程直接退出。

比如:

pthread_t thread1, thread2;

void handler1(void *arg);

void handler2(void*arg);

Int main(int argc, const char*argv[])

{

pthread_create(&thread1, NULL, handler1, NULL);

pthread_create(&thread2, NULL, handler2, NULL);

pthread_join(thread1, NULL);

pthread_join(thread2, NULL);

}

void handler1(void *arg)

{

While (1);

}

void handler2(void *arg)

{

pthread_kill(thread1, SIGKILL);

pthread_exit(0);

}

线程2一旦发送SIGKILL信号,那么会导致整个进程也立刻退出。

二、信号的捕捉处理

常用的信号捕捉处理函数有两个。

1)signal函数

typedef void (*sighandler_t)(int);

sighandler_t signal(int signum, sighandler_t handler);

参数 signum就是signal函数要捕捉的信号,参数handler就是对捕捉信号的处理函数。

示例代码:让程序在执行过程中不受crtl + C的影响

void handler(int signo)

{

printf(“SIGINT is ignore\n”);

}

Int main()

{

….

signal(SIGINT, handler);

….

}

2) sigaction函数

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

参数signum: 要捕捉的信号

act : 对信号处理的结构体

oldact: 用来保存旧的信号处理方式的结构体

struct sigaction的定义如下:

struct sigaction {

void (*sa_handler)(int);

void (*sa_sigaction)(int, siginfo_t *, void *);

sigset_t sa_mask;

int sa_flags;

void (*sa_restorer)(void);

};

igaction函数的功能要比signal函数要强大,但是使用也比较复杂。

示例代码:

void handler(int signo)

{

printf(“SIGINT is ignore\n”);

}

Int main()

{

struct sigaction new, old;

new.sa_handler = handler;

sigemptyset(&new.sa_mask);

new.sa_flags = 0;


sigaction(SIGINT, NULL, &old);

if (old.sa_handler != SIG_IGN)

{

sigaction(SIGINT, &new, NULL);

}

…….

}

扫码申领本地嵌入式教学实录全套视频及配套源码

上一篇:Android USB Host与HID 通讯(一)

下一篇:安卓开发中使用缓冲机制

400-611-6270

Copyright © 2004-2024 华清远见教育科技集团 版权所有
京ICP备16055225号-5京公海网安备11010802025203号