?? 2.html
字號(hào):
SIGPIPE 13在無(wú)讀者的管道上寫(xiě) 是<br>SIGALRM 14 報(bào)時(shí)信號(hào) 是<br>SIGTERM 15終止信號(hào) 是<br>SIGURG 16 IO信道緊急信號(hào) 否<br>SIGSTOP 17暫停信號(hào) 是<br>SIGTSTP 18 交互暫停信號(hào) 是<br>SIGCONT 19如果暫停則繼續(xù) 是<br>SIGCHLD 20 子線(xiàn)程終止或暫停 是<br>SIGTTIN 21后臺(tái)線(xiàn)程組一成員試圖從控制終端上讀出 是<br>SIGTTOU 22 后臺(tái)線(xiàn)程組的成員試圖寫(xiě)到控制終端上 是<br>SIGIO 23允許I/O信號(hào) 否<br>SIGXCPU 24 超出CPU時(shí)限 否<br>SIGXFSZ25 超出文件大小限制 否<br>SIGVTALRM 26 虛時(shí)間警報(bào)器 否<br>SIGPROF27 側(cè)面時(shí)間警報(bào)器 否<br>SIGWINCH 28 窗口大小的更改 否<br>SIGINFO29 消息請(qǐng)求 否<br>SIGUSR1 30 保留作為用戶(hù)自定義的信號(hào)1 是<br>SIGUSR2 31 保留作為用戶(hù)自定義的信號(hào) 是<p>請(qǐng)求按默認(rèn)的規(guī)則進(jìn)行信號(hào)處理<br>SIG_DFL (void (*)(int))0<br>請(qǐng)求忽略信號(hào)<br>SIG_IGN (void (*)(int)) 1<br>注意:信號(hào)隊(duì)列中最多允許有64個(gè)信號(hào)<p><br>3.2 pthreads/pthread_ipc.c<p>此源碼文件包括了一套完整的消息隊(duì)列型線(xiàn)程通信機(jī)制,消息隊(duì)列是線(xiàn)程通信的主要手段,通過(guò)閱讀下面的函數(shù)分析,將使讀者了解OSKit到底是用什么函數(shù)來(lái)具體實(shí)現(xiàn)信號(hào)隊(duì)列,從而進(jìn)行線(xiàn)程通信的。<p>3.2.1消息發(fā)送:<br>說(shuō)明:當(dāng)一個(gè)線(xiàn)程要向另一個(gè)線(xiàn)程發(fā)送消息的時(shí)候,OSKit使用下面定義的函數(shù)來(lái)實(shí)現(xiàn)一個(gè)線(xiàn)程向另一個(gè)線(xiàn)程傳遞消息。<br>oskit_error_toskit_ipc_send ( pthread_t dst,void *msg,<br> oskit_size_t msg_size,oskit_s32_t timeout)<br> dst:目標(biāo)地址 *msg:指向消息的指針<br> msg_size:消息大小(32位無(wú)符號(hào)整形) timeout:超時(shí)<p>3.2.2send的算法<br>發(fā)送一個(gè)同步消息,直到接收者發(fā)送終止消息或超時(shí)才結(jié)束<br>為避免死鎖,給沒(méi)個(gè)人加一個(gè)鎖,并關(guān)中斷。<br>assert_interrupts_enabled();<br>disable_interrupts( );<br>pthread_lock(target->waitlock);<br>通過(guò)條件,檢測(cè)目標(biāo)線(xiàn)程是否在等待接受:<br>條件: a:目標(biāo)線(xiàn)程的等待標(biāo)志 THREAD_WS_IPCRECV_WAIT(線(xiàn)程接收等待位)<br> b:目標(biāo)線(xiàn)程號(hào)存在<br>c:目標(biāo)線(xiàn)程等于任意一個(gè)線(xiàn)程<br> d:消息大小不為0<br>條件成立: a ( b || c) d== 1 才可以發(fā)送<br> if (target->waitflags THREAD_WS_IPCRECV_WAIT<br> (target->ipc_state.tid ==pthread->tid||target->ipc_state.tid== ANYTID))<br> { if(msg_size)<br> {Memcpy(target->ipc_state.msg,<br> msg,MIN(msg_size,target->ipc_state.msg_size));<br> if(msg_size > target->ipc_state.msg_size)<br> err =OSKIT_ERANGE;<br> }<br> }<br>把數(shù)據(jù)的大小和發(fā)送者的ID告訴接受線(xiàn)程:<br>target->ipc_state.msg_size= msg_size;<br>target->ipc_state.tid =pthread->tid;<br>清除接受位:<br>target->waitflags =~THREAD_WS_IPCRECV_WAIT;<br>pthread_unlock ( target->waitlock);<br>注意: flagA = ~flagB實(shí)際上就是將flagB中等于1的位在flagB中清0<br>發(fā)送隊(duì)列:<br>queue_enter (target->ipc_state.senders,pthread,pthread_thread_t*,<br>ipc_state.senders_chain)<br>target->ipc_state.senders:發(fā)送線(xiàn)程的IDpthread:<br>pthread_thread_t*:指向消息的指針是pthread_thread_t類(lèi)型<br>ipc_state.senders_chain:發(fā)送隊(duì)列的指針<br>隊(duì)列間參數(shù)傳遞:<br>pthread->ipc_state.msg= msg; /* 消息 */<br>pthread->ipc_state.msg_size = msg_size; /* 消息的長(zhǎng)度*/<br>pthread->ipc_state.tid = dst; /* 消息的目的地址 */<br>pthread->waitflags =THREAD_WS_IPCSEND_WAIT;<br>/* 消息目的等待位置1 */<p>3.2.3消息接收<br>說(shuō)明:當(dāng)一個(gè)線(xiàn)程要從其消息隊(duì)列中開(kāi)始接受消息的時(shí)候,OSKit提供了下面的函數(shù)供線(xiàn)程調(diào)用。<br>oskit_error_toskit_ipc_recv ( pthread_t src,void *msg,<br> oskit_size_t msg_size,oskit_size_t *actual,oskit_s32_t timeout )<br> src: 發(fā)送線(xiàn)程的ID *msg: 指向消息的指針<br> msg_size: 消息大小(32位無(wú)符號(hào)整形)<br> actual: 實(shí)際消息的大小 timeout: 超時(shí)<p>3.2.4receive的算法<br>等待從發(fā)送線(xiàn)程來(lái)的消息<br>通過(guò)條件,檢測(cè)是否接受消息<br>a:有等待發(fā)送的線(xiàn)程<br>b:線(xiàn)程等待位THREAD_WS_IPCSEND_WAIT(發(fā)送等待標(biāo)志)<br>c:發(fā)送線(xiàn)程存在<br>條件成立:a(b||c)<br> pthread_lock(source->waitlock);<br> if(source->waitflags THREAD_WS_IPCSEND_WAIT<br> source->ipc_state.tid == pthread->tid){<br> *actual = MIN(msg_size, source->ipc_state.msg_size);<br> if(*actual) {<br> memcpy(msg, source->ipc_state.msg,*act0ual);<br> if (source->ipc_state.msg_size >msg_size)<br> err =OSKIT_ERANGE;<br> }<br> }<br>如果沒(méi)有等待發(fā)送的進(jìn)程,則讓接受進(jìn)程等待<br>當(dāng)發(fā)送隊(duì)列為空且timeout=0時(shí)解鎖,如果發(fā)送了但沒(méi)接受,則重新初始化發(fā)送進(jìn)程,重新發(fā)送。<p><br>3.3 pthreads/pthread_signal.c<p>此源碼文件包括了一套完整的信號(hào)量型線(xiàn)程通信機(jī)制,信號(hào)量是線(xiàn)程通信的另一個(gè)重要的手段,通過(guò)閱讀下面的函數(shù)分析,將使讀者了解OSKit到底是用什么函數(shù)來(lái)具體實(shí)現(xiàn)信號(hào)量,從而進(jìn)行線(xiàn)程通信的。<p>3.3.1檢測(cè)并更改阻塞的信號(hào)<br>說(shuō)明:當(dāng)一個(gè)信號(hào)被發(fā)送出來(lái)的時(shí)候,并不一定馬上能得到相應(yīng),一般來(lái)說(shuō),它要被阻塞一段時(shí)間,但系統(tǒng)也是就不管這些阻塞信號(hào)了,系統(tǒng)會(huì)定時(shí)執(zhí)行此線(xiàn)程,用以檢測(cè)阻塞的到底是什么信號(hào),它的含義是什么,然后根據(jù)需求作出決定,可以將信號(hào)阻塞或者響應(yīng)。<br>intpthread_sigmask ( int how, const sigset_t *set, sigset_t *oset )<br> how:SIG_BLOCK SIG_UNBLOCK SIG_SETMASK<br> set:如果是空指針,則指向下一個(gè)信號(hào)<br> oset:如果是空指針,則指向上一個(gè)信號(hào)記錄<p>3.3.2殺線(xiàn)程信號(hào)<br>說(shuō)明:OSKit以及所有的操作系統(tǒng),都包含這個(gè)函數(shù),因?yàn)樗遣僮飨到y(tǒng)所必須具備的基本功能,也就是說(shuō),當(dāng)一個(gè)線(xiàn)程出于無(wú)響應(yīng)狀態(tài)很長(zhǎng)時(shí)間,或者因?yàn)槠渌氖裁丛蚓€(xiàn)程不能得到執(zhí)行,則調(diào)用它,將該線(xiàn)程殺死。<br>intpthread_kill(pthread_t tid, int signo)<p>3.3.3關(guān)線(xiàn)程鎖<br>說(shuō)明:當(dāng)線(xiàn)程接受到了消息后的響應(yīng)過(guò)程中,有些時(shí)候是不希望被其他的線(xiàn)程打斷的,所以O(shè)SKit提供了此函數(shù)調(diào)用,用來(lái)將線(xiàn)程鎖起來(lái),也可以理解為將線(xiàn)程保護(hù)了起來(lái)。<br>intpthread_kill_locked ( pthread_thread_t *pthread, int signo )<p>3.3.4在目標(biāo)線(xiàn)程的信號(hào)等待隊(duì)列中加一個(gè)信號(hào)<br>說(shuō)明:在信號(hào)發(fā)送和接受的過(guò)程中,線(xiàn)程間通訊并不一定是同步的,此時(shí),OSKit提供了一個(gè)消息等待隊(duì)列,將不能及時(shí)得到響應(yīng)的消息用指針鏈接成為一個(gè)類(lèi)似與鏈表的數(shù)據(jù)結(jié)構(gòu)。當(dāng)接受線(xiàn)程要響應(yīng)信號(hào)的時(shí)候可以直接從消息隊(duì)列里提取,這樣作既可以提高通信效率,有可以增加通信的穩(wěn)定性。<br>intsigaddset ( pthread->sigpending, signo )<p>3.3.5信號(hào)完成的動(dòng)作<br>說(shuō)明:在用信號(hào)方式通信的時(shí)候,線(xiàn)程間傳遞的信號(hào)并不是要做的動(dòng)作,而是動(dòng)作的代碼,而什么信號(hào)對(duì)應(yīng)什么動(dòng)作,還要有此漢說(shuō)來(lái)進(jìn)行解析,這樣作是為了規(guī)范線(xiàn)程間通信,同時(shí)還可以節(jié)約空間,節(jié)省發(fā)送和接受的時(shí)間,從而大大提高系統(tǒng)的效率。<br>intsigaction ( int sig, const struct sigaction *act, struct sigaction *oact)<br> sig:指定信號(hào) act:指向與指定信號(hào)向聯(lián)系的規(guī)定信號(hào)動(dòng)作的結(jié)構(gòu)<br> oact:指向存儲(chǔ)先前與該信號(hào)相聯(lián)系的動(dòng)作的結(jié)構(gòu)<p>3.3.6測(cè)試或改變(或兩者兼有)主調(diào)進(jìn)程的信號(hào)掩碼<br>說(shuō)明:所謂掩碼就是信號(hào)的屏蔽碼,比如說(shuō),當(dāng)一個(gè)信號(hào)被發(fā)送的時(shí)候,它被自動(dòng)加載到接收線(xiàn)程的信號(hào)掩碼中,如果此時(shí)又向該線(xiàn)程發(fā)送了同樣的信號(hào),則阻塞該信號(hào),知道前一個(gè)信號(hào)響應(yīng)完畢。<br>OSKit采用下面的函數(shù)完成的對(duì)信息掩碼的測(cè)試和改變。<br>intsigprocmask ( int how, const sigset_t *set, sigset_t *oset )<br> how:指明改變信號(hào)集的方式<br> SIG_BLOCK: 結(jié)果是當(dāng)前集與實(shí)參set所指向的信號(hào)集的聯(lián)合<br> SIG_UNBLOCK:結(jié)果集是當(dāng)前集與實(shí)參set所指向的信號(hào)集的補(bǔ)集的交<br> SIG_SETMASK: 結(jié)果集是實(shí)參set所指向的信號(hào)集<br> set:指向要用來(lái)改變當(dāng)前被阻塞的信號(hào)集 oset: 存儲(chǔ)當(dāng)前的掩碼<p>3.3.7殺線(xiàn)程<br>說(shuō)明:此函數(shù)和前面介紹過(guò)的殺線(xiàn)程信號(hào)并不完全一樣,源線(xiàn)程是通過(guò)看是否有向目的線(xiàn)程發(fā)信號(hào)的權(quán)限,如果有的話(huà)就殺掉它<br>intkill ( pid_t pid, int signo )<br> pid: 目標(biāo)線(xiàn)程 signo: 所要發(fā)的信號(hào)<p>3.3.8等待信號(hào)的線(xiàn)程隊(duì)列<br>說(shuō)明:由于線(xiàn)程間通信不一定同步的原因,調(diào)用此函數(shù)創(chuàng)建信號(hào)等待隊(duì)列是十分有必要的。<br>int sigqueue( pid_t pid, int signo, const union sigval value )<p>3.3.9等待內(nèi)部信號(hào)<br>說(shuō)明:OSKit將信號(hào)分為內(nèi)部信號(hào)和外部信號(hào),這是十分有意義的,因?yàn)楹芏嗲闆r下,它們的處理方式是不一樣的,有的外部消息可以不加理睬,但一般來(lái)說(shuō),內(nèi)部消息是一定要及時(shí)響應(yīng)的,系統(tǒng)通過(guò)調(diào)用下面的函數(shù)實(shí)現(xiàn)了等待一個(gè)內(nèi)部信號(hào),一旦等到,馬上響應(yīng)。<br>oskit_error_toskit_sigwait_internal ( const sigset_t *set,siginfo_t<br> *info,constoskit_timespec_t *timeout )<br> sigset_t: 信號(hào)裝置,無(wú)符號(hào)整型<br> siginfo_t:信號(hào)信息不會(huì)被外部的信號(hào)打斷<p>3.3.10線(xiàn)程等待信號(hào)<br>說(shuō)明:在線(xiàn)程調(diào)度時(shí),調(diào)度程序經(jīng)常會(huì)發(fā)送此信號(hào)讓執(zhí)行完畢的線(xiàn)程等待還沒(méi)執(zhí)行完的線(xiàn)程,這是為了保持線(xiàn)程之間的同步。<br>intsigwait ( const sigset_t *set, int *sig )<p>3.3.11 線(xiàn)程等待信號(hào)(一般指內(nèi)部信號(hào))<br>說(shuō)明:同樣的,核心內(nèi)的線(xiàn)程一樣也要保持同步。<br>intsigwaitinfo ( const sigset_t *set, siginfo_t *info )<p>3.3.12線(xiàn)程等待信號(hào)(有時(shí)間限制)<br>說(shuō)明:此外為了完善系統(tǒng)的線(xiàn)程管理,OSKit還提供了這條函數(shù),用來(lái)設(shè)定線(xiàn)程的等待時(shí)間,如果在規(guī)定的時(shí)間內(nèi)沒(méi)有信號(hào)到來(lái)的話(huà),則
?? 快捷鍵說(shuō)明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -