亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频

? 歡迎來到蟲蟲下載站! | ?? 資源下載 ?? 資源專輯 ?? 關于我們
? 蟲蟲下載站

?? linux環境進程間通信(二):信號(下).htm

?? 本資源中含有有關LINUX進程通信的一些文章
?? HTM
?? 第 1 頁 / 共 4 頁
字號:
            <BLOCKQUOTE>在信號(上)中,討論了linux信號種類、來源、如何安裝一個信號以及對信號集的操作。本部分則首先討論從信號的生命周期上認識信號,或者宏觀上看似簡單的信號機制(進程收到信號后,作相應的處理,看上去再簡單不過了),在微觀上究竟是如何實現的,也是在更深層次上理解信號。接下來還討論了信號編程的一些注意事項,最后給出了信號編程的一些實例。</BLOCKQUOTE>
            <P><A name=1><SPAN 
            class=atitle2>一、信號生命周期</SPAN></A><BR>從信號發送到信號處理函數的執行完畢</P>
            <P>對于一個完整的信號生命周期(從信號發送到相應的處理函數執行完畢)來說,可以分為三個重要的階段,這三個階段由四個重要事件來刻畫:信號誕生;信號在進程中注冊完畢;信號在進程中的注銷完畢;信號處理函數執行完畢。相鄰兩個事件的時間間隔構成信號生命周期的一個階段。</P>
            <P><IMG height=34 alt="" src="" width=594></P>
            <P>下面闡述四個事件的實際意義:</P>
            <OL>
              <LI>信號"誕生"。信號的誕生指的是觸發信號的事件發生(如檢測到硬件異常、定時器超時以及調用信號發送函數kill()或sigqueue()等)。 

              <LI>信號在目標進程中"注冊";進程的task_struct結構中有關于本進程中未決信號的數據成員: <PRE><CODE>struct sigpending pending:
struct sigpending{
	struct sigqueue *head, **tail;
	sigset_t signal;
};
</PRE></CODE><FONT 
              face="宋體, MS Song">第三個成員是進程中所有未決信號集,第一、第二個成員分別指向一個sigqueue類型的結構鏈(稱之為"未決信號信息鏈")的首尾,信息鏈中的每個sigqueue結構刻畫一個特定信號所攜帶的信息,并指向下一個sigqueue結構: 
              </FONT><PRE><CODE>struct sigqueue{
	struct sigqueue *next;
	siginfo_t info;
}
</PRE></CODE><FONT 
              face="宋體, MS Song">信號在進程中注冊指的就是信號值加入到進程的未決信號集中(sigpending結構的第二個成員sigset_t 
              signal),并且信號所攜帶的信息被保留到未決信號信息鏈的某個sigqueue結構中。只要信號在進程的未決信號集中,表明進程已經知道這些信號的存在,但還沒來得及處理,或者該信號被進程阻塞。 
              </FONT>
              <P><B>注:</B><BR>當一個實時信號發送給一個進程時,不管該信號是否已經在進程中注冊,都會被再注冊一次,因此,信號不會丟失,因此,實時信號又叫做"可靠信號"。這意味著同一個實時信號可以在同一個進程的未決信號信息鏈中占有多個sigqueue結構(進程每收到一個實時信號,都會為它分配一個結構來登記該信號信息,并把該結構添加在未決信號鏈尾,即所有誕生的實時信號都會在目標進程中注冊);<BR>當一個非實時信號發送給一個進程時,如果該信號已經在進程中注冊,則該信號將被丟棄,造成信號丟失。因此,非實時信號又叫做"不可靠信號"。這意味著同一個非實時信號在進程的未決信號信息鏈中,至多占有一個sigqueue結構(一個非實時信號誕生后,(1)、如果發現相同的信號已經在目標結構中注冊,則不再注冊,對于進程來說,相當于不知道本次信號發生,信號丟失;(2)、如果進程的未決信號中沒有相同信號,則在進程中注冊自己)。</P>
              <LI>信號在進程中的注銷。在目標進程執行過程中,會檢測是否有信號等待處理(每次從系統空間返回到用戶空間時都做這樣的檢查)。如果存在未決信號等待處理且該信號沒有被進程阻塞,則在運行相應的信號處理函數前,進程會把信號在未決信號鏈中占有的結構卸掉。是否將信號從進程未決信號集中刪除對于實時與非實時信號是不同的。對于非實時信號來說,由于在未決信號信息鏈中最多只占用一個sigqueue結構,因此該結構被釋放后,應該把信號在進程未決信號集中刪除(信號注銷完畢);而對于實時信號來說,可能在未決信號信息鏈中占用多個sigqueue結構,因此應該針對占用sigqueue結構的數目區別對待:如果只占用一個sigqueue結構(進程只收到該信號一次),則應該把信號在進程的未決信號集中刪除(信號注銷完畢)。否則,不應該在進程的未決信號集中刪除該信號(信號注銷完畢)。<BR>進程在執行信號相應處理函數之前,首先要把信號在進程中注銷。 

              <LI>信號生命終止。進程注銷信號后,立即執行相應的信號處理函數,執行完畢后,信號的本次發送對進程的影響徹底結束。 
              <P><B>注:</B><BR>1)信號注冊與否,與發送信號的函數(如kill()或sigqueue()等)以及信號安裝函數(signal()及sigaction())無關,只與信號值有關(信號值小于SIGRTMIN的信號最多只注冊一次,信號值在SIGRTMIN及SIGRTMAX之間的信號,只要被進程接收到就被注冊)。<BR>2)在信號被注銷到相應的信號處理函數執行完畢這段時間內,如果進程又收到同一信號多次,則對實時信號來說,每一次都會在進程中注冊;而對于非實時信號來說,無論收到多少次信號,都會視為只收到一個信號,只在進程中注冊一次。</P></LI></OL>
            <P><A name=2><SPAN class=atitle2>二、信號編程注意事項</SPAN></A></P>
            <OL>
              <LI>防止不該丟失的信號丟失。如果對八中所提到的信號生命周期理解深刻的話,很容易知道信號會不會丟失,以及在哪里丟失。 
              <LI><B>程序的可移植性</B><BR>考慮到程序的可移植性,應該盡量采用POSIX信號函數,POSIX信號函數主要分為兩類: 
              <UL>
                <LI>POSIX 1003.1信號函數: 
                Kill()、sigaction()、sigaddset()、sigdelset()、sigemptyset()、sigfillset()、sigismember()、sigpending()、sigprocmask()、sigsuspend()。 

                <LI>POSIX 1003.1b信號函數。POSIX 1003.1b在信號的實時性方面對POSIX 
                1003.1做了擴展,包括以下三個函數: 
                sigqueue()、sigtimedwait()、sigwaitinfo()。其中,sigqueue主要針對信號發送,而sigtimedwait及sigwaitinfo()主要用于取代sigsuspend()函數,后面有相應實例。 
<PRE><CODE>#include &lt;signal.h&gt;
int sigwaitinfo(sigset_t *set, siginfo_t *info).
</PRE></CODE><FONT 
                face="宋體, MS Song">該函數與sigsuspend()類似,阻塞一個進程直到特定信號發生,但信號到來時不執行信號處理函數,而是返回信號值。因此為了避免執行相應的信號處理函數,必須在調用該函數前,使進程屏蔽掉set指向的信號,因此調用該函數的典型代碼是: 
                </FONT><PRE><CODE>sigset_t newmask;
int rcvd_sig; 
siginfo_t info;

sigemptyset(&amp;newmask);
sigaddset(&amp;newmask, SIGRTMIN);
sigprocmask(SIG_BLOCK, &amp;newmask, NULL);
rcvd_sig = sigwaitinfo(&amp;newmask, &amp;info) 
if (rcvd_sig == -1) {
	..
}
</PRE></CODE><FONT 
                face="宋體, MS Song">調用成功返回信號值,否則返回-1。sigtimedwait()功能相似,只不過增加了一個進程等待的時間。 
                </FONT></LI></UL>
              <LI><B>程序的穩定性。</B><BR>為了增強程序的穩定性,在信號處理函數中應使用可重入函數。 
              <P>信號處理程序中應當使用可再入(可重入)函數(注:所謂可重入函數是指一個可以被多個任務調用的過程,任務在調用時不必擔心數據是否會出錯)。因為進程在收到信號后,就將跳轉到信號處理函數去接著執行。如果信號處理函數中使用了不可重入函數,那么信號處理函數可能會修改原來進程中不應該被修改的數據,這樣進程從信號處理函數中返回接著執行時,可能會出現不可預料的后果。不可再入函數在信號處理函數中被視為不安全函數。</P>
              <P>滿足下列條件的函數多數是不可再入的:(1)使用靜態的數據結構,如getlogin(),gmtime(),getgrgid(),getgrnam(),getpwuid()以及getpwnam()等等;(2)函數實現時,調用了malloc()或者free()函數;(3)實現時使用了標準I/O函數的。The 
              Open Group視下列函數為可再入的: 
              <P><CODE><FONT 
              face=新宋體>_exit()、access()、alarm()、cfgetispeed()、cfgetospeed()、cfsetispeed()、cfsetospeed()、chdir()、chmod()、chown()、close()、creat()、dup()、dup2()、execle()、execve()、fcntl()、fork()、fpathconf()、fstat()、fsync()、getegid()、 
              geteuid()、getgid()、getgroups()、getpgrp()、getpid()、getppid()、getuid()、kill()、link()、lseek()、mkdir()、mkfifo()、 
              open()、pathconf()、pause()、pipe()、raise()、read()、rename()、rmdir()、setgid()、setpgid()、setsid()、setuid()、 
              sigaction()、sigaddset()、sigdelset()、sigemptyset()、sigfillset()、sigismember()、signal()、sigpending()、sigprocmask()、sigsuspend()、sleep()、stat()、sysconf()、tcdrain()、tcflow()、tcflush()、tcgetattr()、tcgetpgrp()、tcsendbreak()、tcsetattr()、tcsetpgrp()、time()、times()、 
              umask()、uname()、unlink()、utime()、wait()、waitpid()、write()。 
              </FONT></CODE>
              <P>即使信號處理函數使用的都是"安全函數",同樣要注意進入處理函數時,首先要保存errno的值,結束時,再恢復原值。因為,信號處理過程中,errno值隨時可能被改變。另外,longjmp()以及siglongjmp()沒有被列為可再入函數,因為不能保證緊接著兩個函數的其它調用是安全的。</P></LI></OL>
            <P><A name=3><SPAN class=atitle2>三、深入淺出:信號應用實例</SPAN></A></P>
            <P>linux下的信號應用并沒有想象的那么恐怖,程序員所要做的最多只有三件事情:</P>
            <OL>
              <LI>安裝信號(推薦使用sigaction()); 
              <LI>實現三參數信號處理函數,handler(int signal,struct siginfo *info, void *); 
              <LI>發送信號,推薦使用sigqueue()。 </LI></OL>
            <P>實際上,對有些信號來說,只要安裝信號就足夠了(信號處理方式采用缺省或忽略)。其他可能要做的無非是與信號集相關的幾種操作。</P>
            <P><B>實例一:信號發送及處理</B><BR>實現一個信號接收程序sigreceive(其中信號安裝由sigaction())。</P><PRE><CODE>#include &lt;signal.h&gt;
#include &lt;sys/types.h&gt;
#include &lt;unistd.h&gt;
void new_op(int,siginfo_t*,void*);
int main(int argc,char**argv)
{
	struct sigaction act;	
	int sig;
	sig=atoi(argv[1]);
	
	sigemptyset(&amp;act.sa_mask);
	act.sa_flags=SA_SIGINFO;
	act.sa_sigaction=new_op;
	
	if(sigaction(sig,&amp;act,NULL) &lt; 0)
	{
		printf("install sigal error\n");
	}
	
	while(1)
	{
		sleep(2);
		printf("wait for the signal\n");
	}
}
void new_op(int signum,siginfo_t *info,void *myact)
{
	printf("receive signal %d", signum);
	sleep(5);
}
</PRE></CODE>
            <P>說明,命令行參數為信號值,后臺運行sigreceive signo 
            &amp;,可獲得該進程的ID,假設為pid,然后再另一終端上運行kill -s signo 
            pid驗證信號的發送接收及處理。同時,可驗證信號的排隊問題。<BR><B>注:</B>可以用sigqueue實現一個命令行信號發送程序sigqueuesend,見<A 
            href="http://www-900.ibm.com/developerWorks/cn/linux/l-ipc/part2/index2.shtml#5">附錄1</A>。 
            </P>
            <P><B>實例二:信號傳遞附加信息</B><BR>主要包括兩個實例:</P>
            <OL>
              <LI>向進程本身發送信號,并傳遞指針參數; <PRE><CODE>#include &lt;signal.h&gt;
#include &lt;sys/types.h&gt;
#include &lt;unistd.h&gt;
void new_op(int,siginfo_t*,void*);
int main(int argc,char**argv)
{
	struct sigaction act;	
	union sigval mysigval;
	int i;
	int sig;
	pid_t pid;		
	char data[10];
	memset(data,0,sizeof(data));
	for(i=0;i &lt; 5;i++)
		data[i]='2';
	mysigval.sival_ptr=data;
	
	sig=atoi(argv[1]);
	pid=getpid();
	
	sigemptyset(&amp;act.sa_mask);
	act.sa_sigaction=new_op;//三參數信號處理函數
	act.sa_flags=SA_SIGINFO;//信息傳遞開關
	if(sigaction(sig,&amp;act,NULL) &lt; 0)
	{
		printf("install sigal error\n");
	}
	while(1)
	{
		sleep(2);
		printf("wait for the signal\n");
		sigqueue(pid,sig,mysigval);//向本進程發送信號,并傳遞附加信息
	}

}

void new_op(int signum,siginfo_t *info,void *myact)//三參數信號處理函數的實現
{
	int i;
	for(i=0;i&lt;10;i++)
	{
		printf("%c\n ",(*( (char*)((*info).si_ptr)+i)));
	}
	printf("handle signal %d over;",signum);
}

</PRE></CODE>
              <P>這個例子中,信號實現了附加信息的傳遞,信號究竟如何對這些信息進行處理則取決于具體的應用。</P>
              <LI>2、 不同進程間傳遞整型參數:把1中的信號發送和接收放在兩個程序中,并且在發送過程中傳遞整型參數。<BR>信號接收程序: <PRE><CODE>#include &lt;signal.h&gt;
#include &lt;sys/types.h&gt;
#include &lt;unistd.h&gt;
void new_op(int,siginfo_t*,void*);
int main(int argc,char**argv)
{
	struct sigaction act;
	int sig;
	pid_t pid;		
	
	pid=getpid();
	sig=atoi(argv[1]);	
	
	sigemptyset(&amp;act.sa_mask);
	act.sa_sigaction=new_op;
	act.sa_flags=SA_SIGINFO;
	if(sigaction(sig,&amp;act,NULL)&lt;0)
	{
		printf("install sigal error\n");
	}
	while(1)
	{
		sleep(2);
		printf("wait for the signal\n");
	}

}
void new_op(int signum,siginfo_t *info,void *myact)
{
	printf("the int value is %d \n",info-&gt;si_int);
}

</PRE></CODE>
              <P>信號發送程序:命令行第二個參數為信號值,第三個參數為接收進程ID。</P><PRE><CODE>#include &lt;signal.h&gt;
#include &lt;sys/time.h&gt;
#include &lt;unistd.h&gt;
#include &lt;sys/types.h&gt;
main(int argc,char**argv)
{
	pid_t pid;
	int signum;
	union sigval mysigval;

	signum=atoi(argv[1]);

?? 快捷鍵說明

復制代碼 Ctrl + C
搜索代碼 Ctrl + F
全屏模式 F11
切換主題 Ctrl + Shift + D
顯示快捷鍵 ?
增大字號 Ctrl + =
減小字號 Ctrl + -
亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频
国产精品天干天干在线综合| 欧美精品久久99久久在免费线 | 欧美天天综合网| 国产成人午夜精品5599| 国产主播一区二区| 国产精品自拍在线| 国产成人激情av| 成人高清在线视频| 成人永久aaa| av在线一区二区| 99精品在线观看视频| 91色porny| 欧美午夜精品一区二区蜜桃| 欧洲一区在线观看| 欧美日韩在线亚洲一区蜜芽| 51精品视频一区二区三区| 91精品国产一区二区三区| 欧美成人aa大片| 国产视频亚洲色图| 亚洲男人的天堂av| 亚洲第一主播视频| 精东粉嫩av免费一区二区三区| 国产一本一道久久香蕉| www.在线成人| 欧美日高清视频| 精品国产露脸精彩对白| 国产精品欧美综合在线| 亚洲国产日韩精品| 国产呦萝稀缺另类资源| 99久久综合色| 91精品国产综合久久久久| 久久久欧美精品sm网站| 亚洲欧美日韩中文播放| 天天操天天干天天综合网| 国产一区二区中文字幕| 欧美视频一区二区三区四区| 日韩免费观看高清完整版 | 成人精品小蝌蚪| 欧美一区日韩一区| 久久久99精品久久| 亚洲第四色夜色| 国产99久久久久久免费看农村| 欧洲一区二区三区免费视频| 精品成人私密视频| 亚洲精品中文在线影院| 国产在线国偷精品产拍免费yy| 欧洲精品在线观看| 国产午夜精品理论片a级大结局 | 精品国产电影一区二区| 亚洲一区二区三区视频在线| 国产一区亚洲一区| 欧美疯狂做受xxxx富婆| 亚洲欧美日韩国产综合| 国产中文字幕一区| 欧美一区二区三区性视频| 一区二区三区欧美视频| 国产成人av影院| 日韩欧美一区二区不卡| 亚洲国产视频网站| 色天天综合色天天久久| 国产精品蜜臀av| 国产一区二区精品在线观看| 欧美一区二视频| 亚洲va中文字幕| 色综合久久88色综合天天| 国产欧美精品在线观看| 国产精品综合二区| 精品国产一区二区三区忘忧草 | 国产亚洲女人久久久久毛片| 美国毛片一区二区| 91精品在线免费观看| 亚洲小少妇裸体bbw| 一本色道久久综合亚洲精品按摩 | 中文字幕二三区不卡| 国产最新精品免费| 精品久久久久久久人人人人传媒| 亚洲福利电影网| 欧美日韩一区二区在线视频| 亚洲香蕉伊在人在线观| 欧美色区777第一页| 亚洲国产wwwccc36天堂| 欧美日韩二区三区| 日韩成人一级片| 欧美一二三区精品| 精品中文字幕一区二区| 国产亚洲一区二区三区四区| 国产一区二区看久久| 国产日产欧美精品一区二区三区| 国产传媒欧美日韩成人| 中文字幕一区二区在线观看 | 一区二区三区四区在线播放| 色综合久久88色综合天天| 99re热视频这里只精品| 一区二区在线观看视频| 91麻豆高清视频| 伊人开心综合网| 51精品久久久久久久蜜臀| 麻豆精品国产91久久久久久| 久久久久久久久久久99999| 懂色av一区二区在线播放| 亚洲精品视频自拍| 日韩丝袜美女视频| 成人免费av在线| 亚洲国产精品嫩草影院| 精品少妇一区二区| 成人一区二区三区| 午夜天堂影视香蕉久久| 精品国产伦一区二区三区免费| 不卡免费追剧大全电视剧网站| 亚洲一区二区三区不卡国产欧美| 宅男噜噜噜66一区二区66| 国产成人av电影在线播放| 亚洲一区精品在线| 国产色产综合产在线视频| 欧美性受xxxx| 国产高清亚洲一区| 午夜精品福利在线| 亚洲国产高清不卡| 在线播放国产精品二区一二区四区 | 另类小说图片综合网| 国产精品萝li| 91精品黄色片免费大全| 91免费在线视频观看| 久久99这里只有精品| 一区二区三区成人在线视频| 337p粉嫩大胆噜噜噜噜噜91av| 色欧美乱欧美15图片| 国产精品18久久久久| 五月天欧美精品| 亚洲欧美成aⅴ人在线观看| 亚洲精品一区二区三区四区高清| 在线观看视频一区二区| 99精品国产热久久91蜜凸| 国产综合色在线| 三级在线观看一区二区| 最新国产成人在线观看| 国产无遮挡一区二区三区毛片日本| 欧美精品高清视频| 欧美中文字幕久久| 97se亚洲国产综合在线| 成人h精品动漫一区二区三区| 久久99精品国产91久久来源| 图片区小说区国产精品视频| 亚洲精选视频在线| 亚洲色图另类专区| 国产精品不卡视频| 中文子幕无线码一区tr| 久久九九久精品国产免费直播| 欧美一区二区大片| 在线电影院国产精品| 欧美三级日本三级少妇99| 91黄色免费看| 欧美专区在线观看一区| 91福利国产成人精品照片| 色婷婷亚洲精品| 日本精品一区二区三区高清| 色中色一区二区| 欧美性大战xxxxx久久久| 欧美亚洲一区二区在线观看| 色欧美日韩亚洲| 欧美日韩电影一区| 91精品国产乱| 精品国产露脸精彩对白| 久久久亚洲精品石原莉奈| 久久综合久色欧美综合狠狠| 久久久久国产免费免费 | 国产精品黄色在线观看 | 91欧美一区二区| 色欧美片视频在线观看在线视频| 一本大道久久a久久综合婷婷| 91麻豆免费看片| 欧美四级电影在线观看| 欧美日本一区二区| 欧美xxxx老人做受| 国产日韩在线不卡| 亚洲男人天堂av| 婷婷国产在线综合| 国产综合久久久久久久久久久久| 国产成人精品亚洲777人妖| 风间由美一区二区av101| 91视视频在线观看入口直接观看www | 国产.欧美.日韩| 91网站最新地址| 欧美一区二区三区啪啪| 国产三级三级三级精品8ⅰ区| 亚洲欧美日韩小说| 日本不卡一区二区| 成人一区二区在线观看| 欧美日韩一区二区在线观看| 欧美成人精品1314www| 国产精品久久二区二区| 日韩综合小视频| 成人美女视频在线观看| 欧美精品第1页| 国产精品久久久久三级| 日本在线不卡视频一二三区| fc2成人免费人成在线观看播放 | 久久久久久夜精品精品免费| 一区二区三区免费在线观看| 国产一区二区三区免费看|