嵌入式linux的学习笔记-进程间通信的信号与信号集(四)
2010-12-17 12:01
543 查看
信号通讯
采用raise发送信号
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <sys/types.h>
#include <sys/wait.h>
int main()
{
pid_t pid; //建立进程ID
int ret;
if((pid=fork())<0)
{
//创建子进程出错,出错处理
}
if(pid==0)
{
//子进程中
raise(SIGSTOP); //子进程发送一个信号
//终止信号
exit(0); //子进程退出
}else
{
printf("pid=%d\n",pid);
if(waitpid(pid,SIGKILL)==0) //等待子进程的关闭,如果成功,则返回0
{
printf("kill %d\n",pid);
exit(0);
}
}
}
pause()
功能:让进程暂停直到信号出现
相关函数: kill,signal,sleep
表头文件: #include<unistd.h>
定义函数: int pause(void);
函数说明: pause()会令目前的进程暂停(进入睡眠状态),直到被信号(signal)所中断。
例子:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int main( void )
{
alarm( 5 ); //定义一个闹钟,5秒后发送一个闹钟超时信号
pause(); //系统挂起,等待一个信号将它唤醒
return 0;
}
//改程序在执行5秒钟后退出
signal 定义一个信号的处理方式或者指定处理函数,这个函数已经在linux里被sigaction所取代,所以尽量不要使用它了
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
void my_func(int sign_no) //用户自定义信号处理程序
{
if(sign_no==SIGINT) //判断信号类型
{
printf("SIGINT\n");
}
if(sign_no==SIGQUIT) //判断信号类型
{
printf("SIGQUIT\n");
}
}
int main()
{
signal(SIGINT,my_func); //注册函数,指定遇到SIGINT时采用用户自定义的my_func函数处理
signal(SIGQUIT,myfunc); //注册函数,指定遇到SIGQUIT时采用用户自定义的my_func函数处理
pause(); //系统挂起,等待信号将它唤醒,当遇到 SIGINT或者SIGQUIT任何一个信号时,进程都会打印对应信息,并且退出
//如果遇到其他信号时,进程将直接退出
exit(0);
}
信号集的处理
int sigemptyset(sigset_t *set); //创建set并且情况信号集
int sigfillset(sigset_t *set); //创建set并使set包含所有linux的信号
int addset(sigset_t *set,int signo); //给set信号集增加一个signo信号
int sigdelset(sigset_t*set,int signo); //将set信号集中的signo定义的信号剔除
以上四个函数成功调用返回0,失败返回1
int sigismember(const sigset_t *set,int signo); //判断set信号集中是否已经包含signo所指向的信号,真返回1,假返回0
int sigprocmask(int how,const sigset_t *set,sigset_t *oset); //设置信号集的屏蔽位,如果oset不为NULL,则oset返回当前修改之前的屏蔽字
how的参数定义
SIG_BLOCK : 屏蔽set所包含的所有信号
SIG_UNBLOCK : 解除set所包含的所有信号
SIG_SETMASK : 直接设置屏蔽信号所指向的值给set信号集
int sigaction(int signo,const struct sigction *act,struct sigaction *oact);
sigaction函数的功能是检测或者修改signo信号关联的处理动作
signo是要检测或者修改具体动作的信号编号数,若act非NULL,则修改它的动作,如果oact非NULL,则返回该信号的原先动作
struct sigaction{
void (*sa_handler)(int signo); //用户自定义处理函数,或者SIG_DFL或者 SIG_IGN
sigset_t sa_mask; //信号集,用来指导在信号处理指向过程中哪些信号要被阻塞
int sa_flags; //信号选项,包括是否则色,是否忽略SIGSTOP,SIGSTP,SIGTTIN,SIGTTOU信号,是否自定义信号只执行一次等等
void (*as_restore);
}
int sigpending(sigset_t *set); //用于检测set信号集中是否为未决的信号,比如在信号集阻塞时的信号
例子
void my_func(int signo) //用户自定义信号处理函数
{
print("test SIGQUIT\n");
}
int main()
{
sigset_t set,pendset; //创建信号集与未决信号集
struct sigaction at1,at2;
sigemptyset(&set);
sigaddset(&set,SIGQUIT);
sigaddset(&set,SIGINT);
sigprocmask(SIG_BLOCK,&set,NULL); //阻塞上述两个添加入信号集的两个信号
sleep(10); //进程休眠10秒,再次期间set信号集的两个信号都无法响应
sigprocmask(SIG_UNBLOCK,&set,NULL); //解除set的阻塞
while(1)
{
if(sigismember(&set,SIGINT)) //检测SIGINT信号是否在我们的set信号集当中
{
sigmptyset(&at1.sa_mask); //滞空信号集
at1.as_handler=myfunc; //指定处理函数
sigaction(SIGINT,&at1,NULL); //注册当遇到SIGINT信号的处理方式
}else if(sigismember(&set,SIGQUIT))
{
sigemptyset(&at2.sa_mask);
at2.sa_handler=SIGDFL; //采用默认方式
sigaction(SIGTERM,&at2,NULL); //注册遇到SIGTERM信号的处理方式
}
}
}
以上的这个例子中,当解除set阻塞后,采用sigaction的方式修改了SIGINT(中断进程,键盘的ctrl+c与)与SIGTERM(软件中断信号,键盘的ctrl+\)的处理方式
采用raise发送信号
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <sys/types.h>
#include <sys/wait.h>
int main()
{
pid_t pid; //建立进程ID
int ret;
if((pid=fork())<0)
{
//创建子进程出错,出错处理
}
if(pid==0)
{
//子进程中
raise(SIGSTOP); //子进程发送一个信号
//终止信号
exit(0); //子进程退出
}else
{
printf("pid=%d\n",pid);
if(waitpid(pid,SIGKILL)==0) //等待子进程的关闭,如果成功,则返回0
{
printf("kill %d\n",pid);
exit(0);
}
}
}
pause()
功能:让进程暂停直到信号出现
相关函数: kill,signal,sleep
表头文件: #include<unistd.h>
定义函数: int pause(void);
函数说明: pause()会令目前的进程暂停(进入睡眠状态),直到被信号(signal)所中断。
例子:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int main( void )
{
alarm( 5 ); //定义一个闹钟,5秒后发送一个闹钟超时信号
pause(); //系统挂起,等待一个信号将它唤醒
return 0;
}
//改程序在执行5秒钟后退出
signal 定义一个信号的处理方式或者指定处理函数,这个函数已经在linux里被sigaction所取代,所以尽量不要使用它了
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
void my_func(int sign_no) //用户自定义信号处理程序
{
if(sign_no==SIGINT) //判断信号类型
{
printf("SIGINT\n");
}
if(sign_no==SIGQUIT) //判断信号类型
{
printf("SIGQUIT\n");
}
}
int main()
{
signal(SIGINT,my_func); //注册函数,指定遇到SIGINT时采用用户自定义的my_func函数处理
signal(SIGQUIT,myfunc); //注册函数,指定遇到SIGQUIT时采用用户自定义的my_func函数处理
pause(); //系统挂起,等待信号将它唤醒,当遇到 SIGINT或者SIGQUIT任何一个信号时,进程都会打印对应信息,并且退出
//如果遇到其他信号时,进程将直接退出
exit(0);
}
信号集的处理
int sigemptyset(sigset_t *set); //创建set并且情况信号集
int sigfillset(sigset_t *set); //创建set并使set包含所有linux的信号
int addset(sigset_t *set,int signo); //给set信号集增加一个signo信号
int sigdelset(sigset_t*set,int signo); //将set信号集中的signo定义的信号剔除
以上四个函数成功调用返回0,失败返回1
int sigismember(const sigset_t *set,int signo); //判断set信号集中是否已经包含signo所指向的信号,真返回1,假返回0
int sigprocmask(int how,const sigset_t *set,sigset_t *oset); //设置信号集的屏蔽位,如果oset不为NULL,则oset返回当前修改之前的屏蔽字
how的参数定义
SIG_BLOCK : 屏蔽set所包含的所有信号
SIG_UNBLOCK : 解除set所包含的所有信号
SIG_SETMASK : 直接设置屏蔽信号所指向的值给set信号集
int sigaction(int signo,const struct sigction *act,struct sigaction *oact);
sigaction函数的功能是检测或者修改signo信号关联的处理动作
signo是要检测或者修改具体动作的信号编号数,若act非NULL,则修改它的动作,如果oact非NULL,则返回该信号的原先动作
struct sigaction{
void (*sa_handler)(int signo); //用户自定义处理函数,或者SIG_DFL或者 SIG_IGN
sigset_t sa_mask; //信号集,用来指导在信号处理指向过程中哪些信号要被阻塞
int sa_flags; //信号选项,包括是否则色,是否忽略SIGSTOP,SIGSTP,SIGTTIN,SIGTTOU信号,是否自定义信号只执行一次等等
void (*as_restore);
}
int sigpending(sigset_t *set); //用于检测set信号集中是否为未决的信号,比如在信号集阻塞时的信号
例子
void my_func(int signo) //用户自定义信号处理函数
{
print("test SIGQUIT\n");
}
int main()
{
sigset_t set,pendset; //创建信号集与未决信号集
struct sigaction at1,at2;
sigemptyset(&set);
sigaddset(&set,SIGQUIT);
sigaddset(&set,SIGINT);
sigprocmask(SIG_BLOCK,&set,NULL); //阻塞上述两个添加入信号集的两个信号
sleep(10); //进程休眠10秒,再次期间set信号集的两个信号都无法响应
sigprocmask(SIG_UNBLOCK,&set,NULL); //解除set的阻塞
while(1)
{
if(sigismember(&set,SIGINT)) //检测SIGINT信号是否在我们的set信号集当中
{
sigmptyset(&at1.sa_mask); //滞空信号集
at1.as_handler=myfunc; //指定处理函数
sigaction(SIGINT,&at1,NULL); //注册当遇到SIGINT信号的处理方式
}else if(sigismember(&set,SIGQUIT))
{
sigemptyset(&at2.sa_mask);
at2.sa_handler=SIGDFL; //采用默认方式
sigaction(SIGTERM,&at2,NULL); //注册遇到SIGTERM信号的处理方式
}
}
}
以上的这个例子中,当解除set阻塞后,采用sigaction的方式修改了SIGINT(中断进程,键盘的ctrl+c与)与SIGTERM(软件中断信号,键盘的ctrl+\)的处理方式
相关文章推荐
- 嵌入式linux的学习笔记-标准文件流管道与命名管道(三)
- LINUX学习笔记-信号SIGNAL
- 嵌入式Linux学习笔记(5)——点亮mini2440 LED
- 使用u-boot的tftp下载功能烧写程序到Nand Flash ——韦东山嵌入式Linux学习笔记09
- LINUX学习笔记15——进程间通信4消息队列
- 嵌入式linux学习笔记(一)
- 嵌入式开发(ARM9)学习笔记(六)-Linux远程登录
- Linux进程间通信IPC学习笔记之消息队列(SVR4)
- 用J-Link烧写u-boot到Nor Flash—— 韦东山嵌入式Linux视频学习笔记04
- TQ2440 学习笔记—— 9、嵌入式编程基础知识【arm-linux-gcc 选项】
- 嵌入式linux c 学习笔记2
- Linux进程间通信——IPC共享内存学习笔记
- Linux信号学习笔记
- Linux进程线程学习笔记:进程间通信 之 管道
- 嵌入式linux的学习笔记-pipe管道(二)
- 开发板、Windows、Ubuntu三者互联——韦东山嵌入式Linux学习笔记08
- 【Linux学习笔记】Unix/Linux 信号详解
- Linux进程间通信IPC学习笔记之同步一(线程、互斥锁和条件变量)
- 嵌入式linux c 学习笔记6-指令
- linux学习笔记-读《Linux编程技术详解》(9)-基本进程间通信方法