仓酷云

 找回密码
 立即注册
搜索
热搜: 活动 交友 discuz
查看: 578|回复: 8
打印 上一主题 下一主题

[CentOS(社区)] 带来一篇Linux过程间通讯

[复制链接]
再见西城 该用户已被删除
跳转到指定楼层
楼主
发表于 2015-1-14 21:04:46 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有帐号?立即注册

x
欢迎大家来到仓酷云论坛!1、过程间通讯概述
过程通讯有以下一些目标:
A、数据传输:一个过程须要将它的数据发送给另外一个过程,发送的数据量在一个字节到几M字节之间
B、同享数据:多个过程想要操作同享数据,一个过程对同享数据的修正,其余过程应当连忙看到。
C、告诉事宜:一个过程须要向另外一个或一组过程发送新闻,告诉它(它们)产生了某种事宜(如过程终止时要告诉父过程)。
D、资本同享:多个过程之间同享异样的资本。为了作到这一点,须要内核供给锁和同步机制。
E、过程掌握:有些过程愿望完整掌握另外一个过程的履行(如Debug过程),此时掌握过程愿望可以或许拦阻另外一个过程的一切堕入和异常,并可以或许实时晓得它的状况转变。
Linux过程间通讯(IPC)以下以几部门成长而来:
晚期UNIX过程间通讯、基于SystemV过程间通讯、基于Socket过程间通讯和POSIX过程间通讯。
UNIX过程间通讯方法包含:管道、FIFO、旌旗灯号。
SystemV过程间通讯方法包含:SystemV新闻队列、SystemV旌旗灯号灯、SystemV同享内存、
POSIX过程间通讯包含:posix新闻队列、posix旌旗灯号灯、posix同享内存。
如今linux应用的过程间通讯方法:
(1)管道(pipe)和著名管道(FIFO)
(2)旌旗灯号(signal)
(3)新闻队列
(4)同享内存
(5)旌旗灯号量
(6)套接字(socket)

2、管道通讯
通俗的Linuxshell都许可重定向,而重定向应用的就是管道。例如:
ps|grepvsftpd.管道是单向的、先辈先出的、无构造的、固定巨细的字撙节,它把一个过程的尺度输入和另外一个过程的尺度输出衔接在一路。写过程在管道的尾端写入数据,读过程在管道的道端读出数据。数据读出后将从管道中移走,其它读过程都不克不及再读到这些数据。管道供给了简略的流掌握机制。过程试图读空管道时,在稀有据写入管道前,过程将一向壅塞。异样,管道曾经满时,过程再试图写管道,在其它过程从管道中移走数据之前,写过程将一向壅塞。管道重要用于分歧过程间通讯。


管道创立与封闭
创立一个简略的管道,可使用体系挪用pipe()。它接收一个参数,也就是一个包含两个整数的数组。假如体系挪用胜利,此数组将包含管道应用的两个文件描写符。创立一个管道以后,普通情形下过程将发生一个新的过程。
体系挪用:pipe();
原型:intpipe(intfd[2]);
前往值:假如体系挪用胜利,前往0。假如体系挪用掉败前往-1:
errno=EMFILE(没有空亲的文件描写符)
EMFILE(体系文件表已满)
EFAULT(fd数组有效)
留意:fd[0]用于读取管道,fd[1]用于写入管道。
图见附件
管道的创立
#include<unistd.h>
#include<errno.h>
#include<stdio.h>
#include<stdlib.h>

intmain()
{
intpipe_fd[2];
if(pipe(pipe_fd)<0){
printf("pipecreateerror
");
return-1;
}
else
printf("pipecreatesuccess
");
close(pipe_fd[0]);
close(pipe_fd[1]);
}

管道的读写
管道重要用于分歧过程间通讯。现实上,平日先创立一个管道,再经由过程fork函数创立一个子过程。图见附件。

子过程写入和父过程读的定名管道:图见附件
管道读写留意事项:
可以经由过程翻开两个管道来创立一个双向的管道。但须要在子理程中准确地设置文件描写符。必需在体系挪用fork()中挪用pipe(),不然子过程将不会继续文件描写符。当应用半双工管道时,任何干联的过程都必需同享一个相干的先人过程。由于管道存在于体系内核当中,所以任何不在创立管道的过程的先人过程当中的过程都将没法寻址它。而在定名管道中却不是如许。管道实例见:pipe_rw.c

#include<unistd.h>
#include<memory.h>
#include<errno.h>
#include<stdio.h>
#include<stdlib.h>

intmain()
{
intpipe_fd[2];
pid_tpid;
charbuf_r[100];
char*p_wbuf;
intr_num;

memset(buf_r,0,sizeof(buf_r));数组中的数据清0;
if(pipe(pipe_fd)<0){
printf("pipecreateerror
");
return-1;
}

if((pid=fork())==0){
printf("
");
close(pipe_fd[1]);
sleep(2);
if((r_num=read(pipe_fd[0],buf_r,100))>0){
printf("%dnumbersreadfrombepipeis%s
",r_num,buf_r);
}
close(pipe_fd[0]);
exit(0);
}elseif(pid>0){
close(pipe_fd[0]);
if(write(pipe_fd[1],"Hello",5)!=-1)
printf("parentwritesuccess!
");
if(write(pipe_fd[1],"Pipe",5)!=-1)
printf("parentwirte2succes!
");
close(pipe_fd[1]);
sleep(3);
waitpid(pid,NULL,0);
exit(0);
}
}


尺度流管道
与linux中文件操作有文件流的尺度I/O一样,管道的操作也支撑基于文件流的形式。接口函数以下:
库函数:popen();
原型:FILE*open(char*command,char*type);
前往值:假如胜利,前往一个新的文件流。假如没法创立过程或许管道,前往NULL。管道中数据流的偏向是由第二个参数type掌握的。此参数可所以r或许w,分离代表读或写。但不克不及同时为读和写。在Linux体系下,管道将会以参数type中第一个字符代表的方法翻开。所以,假如你在参数type中写入rw,管道将会以读的方法翻开。

应用popen()创立的管道必需应用pclose()封闭。其实,popen/pclose和尺度文件输出/输入流中的fopen()/fclose()非常类似。
库函数:pclose();
原型:intpclose(FILE*stream);
前往值:前往体系挪用wait4()的状况。
假如stream有效,或许体系挪用wait4()掉败,则前往-1。留意此库函数期待管道过程运转停止,然后封闭文件流。库函数pclose()在应用popen()创立的过程上履行wait4()函数,它将损坏管道和文件体系。
流管道的例子。
#include<stdio.h>
#include<unistd.h>
#include<stdlib.h>
#include<fcntl.h>
#defineBUFSIZE1024
intmain(){
FILE*fp;
char*cmd="ps-ef";
charbuf[BUFSIZE];
buf[BUFSIZE]=;
if((fp=popen(cmd,"r"))==NULL)
perror("popen");
while((fgets(buf,BUFSIZE,fp))!=NULL)
printf("%s",buf);
pclose(fp);
exit(0);
}

定名管道(FIFO)
根本概念
定名管道和普通的管道根本雷同,但也有一些明显的分歧:
A、定名管道是在文件体系中作为一个特别的装备文件而存在的。
B、分歧先人的过程之间可以经由过程管道同享数据。
C、当同享管道的过程履行完一切的I/O操作今后,定名管道将持续保留在文件体系中以便今后应用。
管道只能由相干过程应用,它们配合的先人过程创立了管道。然则,经由过程FIFO,不相干的过程也能交流数据。

定名管道创立与操作
定名管道创立
#include<sys/types.h>
#include<sys/stat.h>
intmkfifo(constchar*pathname,mode_tmode);
前往:若胜利则为0,若失足前往-1
一旦曾经用mkfifo创立了一个FIFO,便可用open翻开它。确切,普通的文件I/O函数(close,read,write,unlink等)都可用于FIFO。当翻开一个FIFO时,非壅塞标(O_NONBLOCK)发生以下影响:
(1)在普通情形中(没有解释O_NONBLOCK),只读翻开要壅塞到某个其他过程为写翻开此FIFO。相似,为写而翻开一个FIFO要壅塞到某个其他过程为读而翻开它。
(2)假如指一了O_NONBLOCK,则只读翻开立刻前往。然则,假如没有过程曾经为读而翻开一个FIFO,那末只写翻开将失足前往,其errno是ENXIO。相似于管道,若写一个还没有过程为读而翻开的FIFO,则发生旌旗灯号SIGPIPE。若某个FIFO的最初一个写过程封闭了该FIFO,则将为该FIFO的读过程发生一个文件停止标记。
FIFO相干失足信息:
EACCES(无存取权限)
EEXIST(指定文件不存在)
ENAMETOOLONG(路径名太长)
ENOENT(包括的目次不存在)
ENOSPC(文件体系余空间缺乏)
ENOTDIR(文件路径有效)
EROFS(指定的文件存在于只读文件体系中)

fifo_write.c
#include<sys/types.h>
#include<sys/stat.h>
#include<errno.h>
#include<fcntl.h>
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#defineFIFO"/tmp/myfifo"

main(intargc,char**argv)
{
charbuf_r[100];
intfd;
intnread;
if((mkfifo(FIFO,O_CREAT|O_EXCL)<0)&&(errno!=EEXIST))
printf("cannotcreatefifoserver
");
printf("Preparingforreadingbytes....
");
memset(buf_r,0,sizeof(buf_r));
fd=open(FIFO,O_RDONLY|O_NONBLOCK,0);
if(fd==-1)
{
perror("open");
exit(1);
}
while(1){
memset(buf_r,0,sizeof(buf_r));
if((nread=read(fd,buf_r,100))==-1){
if(errno==EAGAIN)
printf("nodatayet
");
}
printf("read%sfromFIFO
",buf_r);
sleep(1);
}
pause();
unlink(FIFO);
}

fifo_read.c
#include<sys/types.h>
#include<sys/stat.h>
#include<errno.h>
#include<fcntl.h>
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#defineFIFO_SERVER"/tmp/myfifo"
main(intargc,char**argv)
{
intfd;
charw_buf[100];
intnwrite;
if(fd==-1)
if(errno==ENXIO)
printf("openerror;noreadingprocess
");
fd=open(FIFO_SERVER,O_WRONLY|O_NONBLOCK,0);
if(argc==1)
printf("Pleasesendsomething
");
strcpy(w_buf,argv[1]);
if((nwrite=write(fd,w_buf,100))==-1)
{
if(errno==EAGAIN)
printf("TheFIFOhasnotbeenreadyet.Pleasetrylater
");
}
else
printf("write%stotheFIFO
",w_buf);
}


3、旌旗灯号
旌旗灯号概述
旌旗灯号是软件中止。旌旗灯号(signal)机制是Unix体系中最为陈旧的过程之间的能信机制。它用于在一个或多个过程之间传递异步旌旗灯号。许多前提可以发生一个旌旗灯号。
A、当用户按某些终端键时,发生旌旗灯号。在终端上按DELETE键平日发生中止旌旗灯号(SIGINT)。这是停滞一个已落空掌握法式的办法。
B、硬件异常发生旌旗灯号:除数为0、有效的存储拜访等等。这些前提平日由硬件检测到,并将其告诉内核。然后内核为该前提产生时正在运转的过程发生恰当的旌旗灯号。例如,关于履行一个有效存储拜访的过程发生一个SIGSEGV。
C、过程用kill(2)函数可将旌旗灯号发送给另外一个过程或过程组。天然,有些限制:吸收旌旗灯号进和发送旌旗灯号过程的一切都必需雷同,或发送旌旗灯号过程的的一切者必需是超等用户。
D、用户可用Kill(ID值)敕令将旌旗灯号发送给其它过程。此法式是Kill函数的界面。经常使用此敕令终止一个掉控的后台过程。
E、当检测到某种软件前提曾经产生,并将其告诉有关过程时也发生旌旗灯号。这里并非指硬件发生前提(如被0除),而是软件前提。例如SIGURG(在收集衔接上传来非划定波特率的数据)、SIGPIPE(在管道的读过程已终止后一个过程写此管道),和SIGALRM(过程所设置的闹钟时光曾经超时)。

内核为过程临盆旌旗灯号,来呼应分歧的事宜,这些事宜就是旌旗灯号源。重要旌旗灯号源以下:
(1)异常:过程运转过程当中涌现异常;
(2)其它过程:一个过程可以向另外一个或一组过程发送旌旗灯号;
(3)终端中止:Ctrl-c,Ctro-等;
(4)功课掌握:前台、后台过程的治理;
(5)分派额:CPU超时或文件巨细冲破限制;
(6)告诉:告诉过程某事宜产生,如I/O停当等;
(7)报警:计时器到期;

Linux中的旌旗灯号
1、SIGHUP2、SIGINT(终止)3、SIGQUIT(加入)4、SIGILL5、SIGTRAP6、SIGIOT7、SIGBUS8、SIGFPE9、SIGKILL10、SIGUSER11、SIGSEGVSIGUSER12、SIGPIPE13、SIGALRM14、SIGTERM15、SIGCHLD16、SIGCONT17、SIGSTOP18、SIGTSTP19、SIGTTIN20、SIGTTOU21、SIGURG22、SIGXCPU23、SIGXFSZ24、SIGVTALRM25、SIGPROF26、SIGWINCH27、SIGIO28、SIGPWR

经常使用的旌旗灯号:
SIGHUP:从终端上收回的停止旌旗灯号;
SIGINT:来自键盘的中止旌旗灯号(Ctrl+c)
SIGQUIT:来自键盘的加入旌旗灯号;
SIGFPE:浮点异常旌旗灯号(例如浮点运算溢出);
SIGKILL:该旌旗灯号停止吸收旌旗灯号的过程;
SIGALRM:过程的准时器到期时,发送该旌旗灯号;
SIGTERM:kill敕令生出的旌旗灯号;
SIGCHLD:标识子过程停滞或停止的旌旗灯号;
SIGSTOP:来自键盘(Ctrl-Z)或调试法式的停滞扫行旌旗灯号

可以请求体系在某个旌旗灯号涌现时依照以下三种方法中的一种停止操作。
(1)疏忽此旌旗灯号。年夜多半旌旗灯号都可以使用这类方法停止处置,但有两种旌旗灯号却决不克不及被疏忽。它们是:SIGKILL和SIGSTOP。这两种旌旗灯号不克不及被疏忽的,缘由是:它们向超等用户供给一种使过程终止或停滞的靠得住办法。别的,假如疏忽某些由硬件异常发生的旌旗灯号(例如不法存储拜访或除以0),则过程的行动是示界说的。
(2)捕获旌旗灯号。为了做到这一点要告诉内核在某种旌旗灯号产生时,挪用一个用户函数。在用户函数中,可履行用户愿望对这类事宜停止的处置。假如捕获到SIGCHLD旌旗灯号,则表现子过程曾经终止,所以此旌旗灯号的捕获函数可以挪用waitpid以获得该子过程的过程ID和它的终止状况。
(3)履行体系默许举措。对年夜多半旌旗灯号的体系默许举措是终止该过程。每个旌旗灯号都有一个缺省举措,它是当过程没有给这个旌旗灯号指定处置法式时,内查对旌旗灯号的处置。有5种缺省的举措:
(1)异常终止(abort):在过程确当前目次下,把过程的地址空间内容、存放器内容保留到一个叫做core的文件中,尔后终止过程。
(2)加入(exit):不发生core文件,直接终止过程。
(3)疏忽(ignore):疏忽该旌旗灯号。
(4)停滞(stop):挂起该过程。
(5)持续(contiune):假如过程被挂起,刚恢复过程的动行。不然,疏忽旌旗灯号。

旌旗灯号的发送与捕获
kill()和raise()
kill()不只可以中断过程,也能够向过程发送其他旌旗灯号。
与kill函数分歧的是,raise()函数运转向过程本身发送旌旗灯号
#include<sys/types.h>
#include<signal.h>
intkill(pid_tpid,intsigno);
intraise(intsigno);
两个函数前往:若胜利则为0,若失足则为-1。
kill的pid参数有四种分歧的情形:
(1)pid>0将旌旗灯号发送给过程ID为pid的过程。
(2)pid==0将旌旗灯号发送给其过程组ID等于发送过程的过程组ID,并且发送过程有允许权向其发送旌旗灯号的一切过程。
(3)pid<0将旌旗灯号发送给其过程组ID等于pid相对值,并且发送过程有允许权向其发送旌旗灯号的一切过程。如上所述一样,“一切过程”其实不包含体系过程集中的过程。
(4)pid==-1POSIX.1不决义种情形
kill.c
#include<stdio.h>
#include<stdlib.h>
#include<signal.h>
#include<sys/types.h>
#include<sys/wait.h>
intmain()
{
pid_tpid;
intret;
if((pid==fork())<0){
perro("fork");
exit(1);
}
if(pid==0){
raise(SIGSTOP);
exit(0);
}else{
printf("pid=%d
",pid);
if((waitpid(pid,NULL,WNOHANG))==0){
if((ret=kill(pid,SIGKILL))==0)
printf("kill%d
",pid);
else{
perror("kill");
}
}
}
}

alarm和pause函数
应用alarm函数可以设置一个时光值(闹钟时光),在未来的某个时辰时光值会被跨越。当所设置的时光被跨越后,发生SIGALRM旌旗灯号。假如不疏忽或不捕获引旌旗灯号,则其默许举措是终止该过程。
#include<unistd.h>
unsignedintalarm(unsignedintsecondss);
前往:0或之前设置的闹钟时光的余留秒数。

参数seconds的值是秒数,经由了指定的seconds秒后发生旌旗灯号SIGALRM。每一个过程只能有一个闹钟时光。假如在挪用alarm时,之前已为该过程设置过闹钟时光,并且它还没有超时,则该闹钟时光的余留值作为本次alarm函数挪用的值前往。之前挂号的闹钟时光则被新值代换。
假如有之前挂号的还没有跨越的闹钟时光,并且seconds值是0,则撤消之前的闹钟时光,其他留值仍作为函数的前往值。


pause函数应用挪用过程挂起直至捕获到一个旌旗灯号
#include<unistd.h>
intpause(void);
前往:-1,errno设置为EINTR
只要履行了一旌旗灯号处置法式并从其前往时,pause才前往。

alarm.c
#include<unistd.h>
#include<stdio.h>
#include<stdlib.h>
intmain()
{
intret;
ret=alarm(5);
pause();
printf("Ihavebeenwakenup.
",ret);
}

旌旗灯号的处置
当体系捕获到某个旌旗灯号时,可以疏忽谁旌旗灯号或是应用指定的处置函数来处置该旌旗灯号,或许应用体系默许的方法。旌旗灯号处置的重要方法有两种,一种是应用简略的signal函数,别一种是应用旌旗灯号集函数组。
signal()
#include<signal.h>
void(*signal(intsigno,void(*func)(int)))(int)
前往:胜利则为之前的旌旗灯号处置设置装备摆设,若失足则为SIG_ERR
func的值是:(a)常数SIGIGN,或(b)常数SIGDFL,或(c)当接到此旌旗灯号后要挪用的的函数的地址。假如指定SIGIGN,则向内核表现疏忽此旌旗灯号(有两个旌旗灯号SIGKILL和SIGSTOP不克不及疏忽)。假如指定SIGDFL,则表现接到此旌旗灯号后的举措是体系默许举措。当指定函数地址时,我们称此为捕获此旌旗灯号。我们称此函数为旌旗灯号处置法式(signalhandler)或旌旗灯号捕获函数(signal-catchingfuncgion).signal函数原型太庞杂了,假如应用上面的typedef,则可使其简化。
typevoidsign(int);
sign*signal(int,handler*);
实例见:mysignal.c
#include<signal.h>
#include<stdio.h>
#include<stdlib.h>
voidmy_func(intsign_no)
{
if(sign_no==SIGINT)
printf("IhavegetSIGINT
");
elseif(sign_no==SIGQUIT)
printf("IhavegetSIGQUIT
");
}
intmain()
{
printf("WaitingforsignalSIGINTorSIGQUTI
");
signal(SIGINT,my_func);
signal(SIGQUIT,my_func);
pasue();
exit(0);
}
旌旗灯号集函数组
我们须要有一个能表现多个旌旗灯号――旌旗灯号集(signalset)的数据类型。将在sigprocmask()如许的函数中应用这类数据类型,以告知内核不许可产生该旌旗灯号集中的旌旗灯号。旌旗灯号集函数组包括水量几年夜模块:创立函数集、挂号旌旗灯号集、检测旌旗灯号集。
图见附件。

创立函数集
#include<signal.h>
intsigemptyset(sigset_t*set);
intsigfillset(sigset_t*set);
intsigaddset(sigset_t*set,intsigno);
intsigdelset(sigset_t*set,intsigno);
四个函数前往:若胜利则为0,若失足则为-1
intsigismember(constsigset_t*set,intsigno);
前往:若真则为1,若假则为0;
signemptyset:初始化旌旗灯号聚集为空。
sigfillset:初始化旌旗灯号聚集为一切的旌旗灯号聚集。
sigaddset:将指定旌旗灯号添加到现存集中。
sigdelset:从旌旗灯号集中删除指定旌旗灯号。
sigismember:查询指定旌旗灯号能否在旌旗灯号集中。

挂号旌旗灯号集
挂号旌旗灯号处置机重要用于决议过程若何处置旌旗灯号。起首要断定出以后过程壅塞能不克不及传递给该旌旗灯号的旌旗灯号集。这起首应用sigprocmask函数断定检测或更改旌旗灯号屏障字,然后应用sigaction函数转变过程接收到特定旌旗灯号以后的行动。
一个过程的旌旗灯号屏障字可以划定以后壅塞而不克不及递送给该过程的旌旗灯号集。挪用函数sigprocmask可以检测或更改(或二者)过程的旌旗灯号屏障字。
#include<signal.h>
intsigprocmask(inthow,constsigset_t*set,sigset_t*oset);
前往:若胜利则为0,若失足则为-1
oset长短空指针,过程是以后旌旗灯号屏障字经由过程oset前往。其次,若set是一个非空指针,则参数how指导若何修正以后旌旗灯号屏障字。
用sigprocmask更改以后旌旗灯号屏障字的办法。how参数设定:
SIG_BLOCK该过程新的旌旗灯号屏障字是其以后旌旗灯号屏障字和set指向旌旗灯号集的并集。set包括了我们愿望壅塞的附加旌旗灯号。
SIG_NUBLOCK该过程新的旌旗灯号屏障字是其以后旌旗灯号屏障字和set所指向旌旗灯号集的交集。set包括了我们愿望消除壅塞的旌旗灯号。
SIG_SETMASK该过程新的旌旗灯号屏障是set指向的值。假如set是个空指针,则不转变该过程的旌旗灯号屏障字,how的值也有意义。
sigaction函数的功效是检讨或修正(或二者)与指定旌旗灯号相干联的处置举措。此函数代替了UNIX晚期版本应用的signal函数。
#include<signal.h>
intsigaction(intsigno,conststructsigaction*act,structsigaction*oact);
前往:若胜利则为0,若失足则为-1
参数signo是要检测或修正详细举措的旌旗灯号的编号数。若act指针非空,则要修正其举措。假如oact指针为空,则体系前往该旌旗灯号的本来举措。此函数应用以下构造:
structsigaction{
void(*sa_handler)(intsigno);
sigset_tsa_mask;
intsa_flags;
void(*sa_restore);
};
sa_handler是一个函数指针,指定旌旗灯号联系关系函数,可所以自界说处置函数,还可以SIG_DEF或SIG_IGN;
sa_mask是一个旌旗灯号集,它可以指定在旌旗灯号处置法式履行过程当中哪些旌旗灯号应该被壅塞。
sa_flags中包括很多标记位,是对旌旗灯号停止处置的各类选项。详细以下:
SA_NODEFERSA_NOMASK:当捕获到此旌旗灯号时,在履行其旌旗灯号捕获函数时,体系不会主动壅塞此旌旗灯号。
SA_NOCLDSTOP:过程疏忽子过程发生的任何SIGSTOP、SIGTSTP、SIGTTIN和SIGTOU旌旗灯号
SA_RESTART:可以让重启的体系挪用从新起感化。
SA_ONESHOTSA_RESETHAND:自界说旌旗灯号只履行一次,在履行终了后恢覆信号的体系默许举措。
检测旌旗灯号是旌旗灯号处置的后续步调,但不是必需的。sigpending函数运转过程检测“未决“旌旗灯号(过程不清晰他的存在),并进一步决议对他们做何处置。
sigpending前往关于挪用过程被壅塞不克不及递送和以后未决的旌旗灯号集。
#include<signal.h>
intsigpending(sigset_t*set);
前往:若胜利则为0,若失足则为-1
旌旗灯号集实例见:sigaction.c
#include<sys/types.h>
#include<unistd.h>
#include<signal.h>
#include<stdio.h>
#include<stdlib.h>
voidmy_func(intsignum){
printf("Ifyouwanttoquit,pleasetrySIGQUIT
");
}
intmain()
{
sigset_tset,pendset;
structsigactionaction1,action2;
if(sigemptyse(&set)<0)
perror("sigemptyset");
if(sigaddset(&set,SIGQUIT)<0)
perror("sigaddset");
if(sigaddset(&set,SIGINT)<0)
perror("sigaddset");
if(sigprocmask(SIG_BLOCK,&set,NULL)<0)
perror("sigprcmask");
esle{
printf("blocked
");
sleep(5);
}
if(sigprocmask(SIG_UNBLOCK,&set,NULL)
perror("sigprocmask");
else
printf("unblock
");
while(1){
if(sigismember(&set,SIGINT)){
sigemptyset(&action1.sa_mask);
action1.sa_handler=my_func;
sigaction(SIGINT,&action1,NULL);
}elseif(sigismember(&set,SIGQUIT)){
sigemptyset(&action2.sa_mask);
action2.sa_handler=SIG_DEL;
sigaction(SIGTERM,&action2,NULL);
}
}
}



欢迎大家来到仓酷云论坛!
不帅 该用户已被删除
沙发
发表于 2015-1-16 11:35:25 | 只看该作者

带来一篇Linux过程间通讯

甚至目前许多应用软件都是基于它的。可是没有哪一个系统是十分完美的。
admin 该用户已被删除
板凳
发表于 2015-1-18 14:34:44 来自手机 | 只看该作者
感谢老师和同学们在学习上对我的帮助。
不帅 该用户已被删除
地板
发表于 2015-1-27 09:10:37 | 只看该作者
掌握硬件配置,如显卡,声卡,网卡等,硬件只要不是太老或太新一般都能被支持,作为一名Linux系统管理员建议多阅读有关硬件配置文章,对各种不支持或支持不太好的硬件有深刻的了解。
兰色精灵 该用户已被删除
5#
发表于 2015-2-5 12:36:56 | 只看该作者
这种补充有助于他人在邮件列表/新闻组/论坛中搜索对你有过帮助的完整解决方案,这可能对他们也很有用。
分手快乐 该用户已被删除
6#
发表于 2015-2-11 22:53:14 | 只看该作者
然我们对Linux的学习首先是通过对它的产生,发展,到今天仍然在不断完善开始的。
金色的骷髅 该用户已被删除
7#
发表于 2015-3-11 08:27:25 | 只看该作者
其实当你安装了一个完整的Linux系统后其中已经包含了一个强大的帮助,只是可能你还没有发现和使用它们的技巧。
山那边是海 该用户已被删除
8#
发表于 2015-3-18 07:38:24 | 只看该作者
虽然大家都比较喜欢漂亮的mm,但是在学 linux 的过程中,还是要多和“男人”接触一下:P 遇到问题的时候,出来看说和上网查之外,就是要多用 linux 下的 man 命令找找帮助。
透明 该用户已被删除
9#
发表于 2015-3-25 21:13:44 | 只看该作者
让我树立了很大的信心学好这门课程,也学到了不少专业知识和技能。?
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|Archiver|手机版|仓酷云 鄂ICP备14007578号-2

GMT+8, 2024-5-15 22:59

Powered by Discuz! X3.2

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表