乡下人产国偷v产偷v自拍,国产午夜片在线观看,婷婷成人亚洲综合国产麻豆,久久综合给合久久狠狠狠9

  • <output id="e9wm2"></output>
    <s id="e9wm2"><nobr id="e9wm2"><ins id="e9wm2"></ins></nobr></s>

    • 分享

      多線程中使用信號(hào)機(jī)制 pthread

       gljin_cn 2016-05-23

      在Linux的多線程中使用信號(hào)機(jī)制,與在進(jìn)程中使用信號(hào)機(jī)制有著根本的區(qū)別,可以說(shuō)是完全不同。在進(jìn)程環(huán)境中,對(duì)信號(hào)的處理是,先注冊(cè)信號(hào)處理函數(shù),當(dāng)信號(hào)異步發(fā)生時(shí),調(diào)用處理函數(shù)來(lái)處理信號(hào)。它完全是異步的(我們完全不知到信號(hào)會(huì)在進(jìn)程的那個(gè)執(zhí)行點(diǎn)到來(lái)!)。然而信號(hào)處理函數(shù)的實(shí)現(xiàn),有著許多的限制;比如有一些函數(shù)不能在信號(hào)處理函數(shù)中調(diào)用;再比如一些函數(shù)read、recv等調(diào)用時(shí)會(huì)被異步的信號(hào)給中斷(interrupt),因此我們必須對(duì)在這些函數(shù)在調(diào)用時(shí)因?yàn)樾盘?hào)而中斷的情況進(jìn)行處理(判斷函數(shù)返回時(shí) enno 是否等于 EINTR)。


      但是在多線程中處理信號(hào)的原則卻完全不同,它的基本原則是:將對(duì)信號(hào)的異步處理,轉(zhuǎn)換成同步處理,也就是說(shuō)用一個(gè)線程專(zhuān)門(mén)的來(lái)“同步等待”信號(hào)的到來(lái),而其它的線程可以完全不被該信號(hào)中斷/打斷(interrupt)。這樣就在相當(dāng)程度上簡(jiǎn)化了在多線程環(huán)境中對(duì)信號(hào)的處理。而且可以保證其它的線程不受信號(hào)的影響。這樣我們對(duì)信號(hào)就可以完全預(yù)測(cè),因?yàn)樗辉偈钱惒降模峭降模?span style="color:#000080">我們完全知道信號(hào)會(huì)在哪個(gè)線程中的哪個(gè)執(zhí)行點(diǎn)到來(lái)而被處理!)。而同步的編程模式總是比異步的編程模式簡(jiǎn)單。其實(shí)多線程相比于多進(jìn)程的其中一個(gè)優(yōu)點(diǎn)就是:多線程可以將進(jìn)程中異步的東西轉(zhuǎn)換成同步的來(lái)處理。

      1. sigwait函數(shù):
      1. sigwait - wait for a signal

      2. #include <signal.h>
      3. int sigwait(const sigset_t *set, int *sig);

      4. Description
      5. The sigwait() function suspends execution of the calling thread until the delivery of one 
      6. of the signals specified in the signal set set. The function accepts the signal (removes 
      7. it from the pending list of signals), and returns the signal number in sig.
      8. The operation of sigwait() is the same as sigwaitinfo(2), except that:

      9. * sigwait() only returns the signal number, rather than a siginfo_t structure describing 
      10.   the signal.
      11. * The return values of the two functions are different.
      12. Return Value
      13. On success, sigwait() returns 0. On error, it returns a positive error number.
      從上面的man sigwait的描述中,我們知道:sigwait是同步的等待信號(hào)的到來(lái),而不是像進(jìn)程中那樣是異步的等待信號(hào)的到來(lái)。sigwait函數(shù)使用一個(gè)信號(hào)集作為他的參數(shù),并且在集合中的任一個(gè)信號(hào)發(fā)生時(shí)返回該信號(hào)值,解除阻塞,然后可以針對(duì)該信號(hào)進(jìn)行一些相應(yīng)的處理。
      2. 記?。?/span>
           在多線程代碼中,總是使用sigwait或者sigwaitinfo或者sigtimedwait等函數(shù)來(lái)處理信號(hào)。
           而不是signal或者sigaction等函數(shù)。因?yàn)樵谝粋€(gè)線程中調(diào)用signal或者sigaction等函數(shù)會(huì)改變所以線程中的
           信號(hào)處理函數(shù)。而不是僅僅改變調(diào)用signal/sigaction的那個(gè)線程的信號(hào)處理函數(shù)。
      3. pthread_sigmask函數(shù):
         每個(gè)線程均有自己的信號(hào)屏蔽集(信號(hào)掩碼),可以使用pthread_sigmask函數(shù)來(lái)屏蔽某個(gè)線程對(duì)某些信號(hào)的
         響應(yīng)處理,僅留下需要處理該信號(hào)的線程來(lái)處理指定的信號(hào)。實(shí)現(xiàn)方式是:利用線程信號(hào)屏蔽集的繼承關(guān)系
        (在主進(jìn)程中對(duì)sigmask進(jìn)行設(shè)置后,主進(jìn)程創(chuàng)建出來(lái)的線程將繼承主進(jìn)程的掩碼
      1. pthread_sigmask - examine and change mask of blocked signals

      2. #include <signal.h>
      3. int pthread_sigmask(int how, const sigset_t *set, sigset_t *oldset);

      4. Compile and link with -pthread.

      5. DESCRIPTION
      6. The pthread_sigmask() function is just like sigprocmask(2), with the difference that its use
      7. in multithreaded programs is explicitly specified by POSIX.1-2001.
      8. Other differences are noted in this page.
      9. For a description of the arguments and operation of this function, see sigprocmask(2).

      10. RETURN VALUE
      11. On success, pthread_sigmask() returns 0; on error, it returns an error number.
      12. NOTES
      13. A new thread inherits a copy of its creator's signal mask.
      14. (from man sigprocmask: )
      15. The behavior of the call is dependent on the value of how, as follows.
      16. SIG_BLOCK
      17. The set of blocked signals is the union of the current set and the set argument.
      18. SIG_UNBLOCK
      19. The signals in set are removed from the current set of blocked signals. It is permissible 
      20. to attempt to unblock a signal which is not blocked.
      21. SIG_SETMASK
      22. The set of blocked signals is set to the argument set.
      23. If oldset is non-NULL, the previous value of the signal mask is stored in oldset.
      24. If set is NULL, then the signal mask is unchanged (i.e., how is ignored), but the current 
      25. value of the signal mask is nevertheless returned in oldset (if it is not NULL).
      4. pthread_kill函數(shù):
         在多線程程序中,一個(gè)線程可以使用pthread_kill對(duì)同一個(gè)進(jìn)程中指定的線程(包括自己)發(fā)送信號(hào)。注意在多線程中  
        一般不使用kill函數(shù)發(fā)送信號(hào),因?yàn)閗ill是對(duì)進(jìn)程發(fā)送信號(hào),結(jié)果是:正在運(yùn)行的線程會(huì)處理該信號(hào),如果該線程沒(méi)有
       注冊(cè)信號(hào)處理函數(shù),那么會(huì)導(dǎo)致整個(gè)進(jìn)程退出。
      1. #include <signal.h>
      2. int pthread_kill(pthread_t thread, int sig);
      3. Compile and link with -pthread.
      4. DESCRIPTION
      5. The pthread_kill() function sends the signal sig to thread, another thread in the same 
      6. process as the caller. The signal is asynchronously directed to thread.
      7. If sig is 0, then no signal is sent, but error checking is still performed; this can be 
      8. used to check for the existence of a thread ID.
      9. RETURN VALUE
      10. On success, pthread_kill() returns 0; on error, it returns an error number, and no signal 
      11. is sent.
      12. ERRORS
      13. ESRCH No thread with the ID thread could be found.
      14. EINVAL An invalid signal was specified.
      5. 記?。?/span>調(diào)用sigwait同步等待的信號(hào)必須在調(diào)用線程中被屏蔽,并且通常應(yīng)該在所有的線程中被屏蔽(這樣可以保證信號(hào)絕不會(huì)被送到除了調(diào)用sigwait的任何其它線程),這是通過(guò)利用信號(hào)掩碼的繼承關(guān)系來(lái)達(dá)到的。
      (The semantics of sigwait require that all threads (including the thread calling sigwait) have the signal masked, for
        reliable operation. Otherwise, a signal that arrives not blocked in sigwait might be  delivered to another thread.)
      6. 代碼示例:(from man pthread_sigmask)
      1. #include <pthread.h>
      2. #include <stdio.h>
      3. #include <stdlib.h>
      4. #include <unistd.h>
      5. #include <signal.h>
      6. #include <errno.h>

      7. /* Simple error handling functions */

      8. #define handle_error_en(en, msg) \
      9.         do { errno = en; perror(msg); exit(EXIT_FAILURE); } while (0)

      10. static void *
        1. sig_thread(void *arg)
      11. {
      12.       sigset_t *set = (sigset_t *) arg;
      13.       int s, sig;

      14.       for (;;) {
      15.             s = sigwait(set, &sig);
      16.             if (s != 0)
      17.                   handle_error_en(s, "sigwait");
      18.             printf("Signal handling thread got signal %d\n", sig);
      19.       }
      20. }

      21. int
        1. main(int argc, char *argv[])
      22. {
      23.       pthread_t thread;
      24.       sigset_t set;
      25.       int s;

      26.       /* 
      27.          Block SIGINT; other threads created by main() will inherit
      28.          a copy of the signal mask. 
      29.        */
      30.       sigemptyset(&set);
      31.       sigaddset(&set, SIGQUIT);
      32.       sigaddset(&set, SIGUSR1);
      33.       s = pthread_sigmask(SIG_BLOCK, &set, NULL);
      34.       if (s != 0)
      35.             handle_error_en(s, "pthread_sigmask");
      36.       s = pthread_create(&thread, NULL, &sig_thread, (void *) &set);
      37.       if (s != 0)
      38.             handle_error_en(s, "pthread_create");
      39.       /* 
      40.         Main thread carries on to create other threads and/or do
      41.         other work 
      42.        */
      43.       pause(); /* Dummy pause so we can test program */
      44.       return 0;
      45. }
      編譯運(yùn)行情況:
      1. digdeep@ubuntu:~/pthread/learnthread$ gcc -Wall -pthread -o pthread_sigmask pthread_sigmask.c
      2. digdeep@ubuntu:~/pthread/learnthread$ ./pthread_sigmask &
      3. [1] 4170
      4. digdeep@ubuntu:~/pthread/learnthread$ kill -QUIT %1
      5. digdeep@ubuntu:~/pthread/learnthread$ Signal handling thread got signal 3

      6. digdeep@ubuntu:~/pthread/learnthread$ kill -USR1 %1
      7. digdeep@ubuntu:~/pthread/learnthread$ Signal handling thread got signal 10

      8. digdeep@ubuntu:~/pthread/learnthread$ kill -TERM %1
      9. digdeep@ubuntu:~/pthread/learnthread$
      10. [1]+ Terminated ./pthread_sigmask
      11. digdeep@ubuntu:~/pthread/learnthread$
      這個(gè)例子演示了:通過(guò)在主線程中阻塞一些信號(hào),其它的線程會(huì)繼承信號(hào)掩碼,然后專(zhuān)門(mén)用一個(gè)線程使用sigwait函數(shù)來(lái)同步的處理信號(hào),使其它的線程不受到信號(hào)的影響。

        本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購(gòu)買(mǎi)等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
        轉(zhuǎn)藏 分享 獻(xiàn)花(0

        0條評(píng)論

        發(fā)表

        請(qǐng)遵守用戶 評(píng)論公約

        類(lèi)似文章 更多