• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            Prayer

            在一般中尋求卓越
            posts - 1256, comments - 190, trackbacks - 0, articles - 0
              C++博客 :: 首頁 :: 新隨筆 :: 聯系 :: 聚合  :: 管理

            這幾天把一個網絡流量采集器程序基本改好了,原來在main函數中把幾個子線程啟動后就睡10分鐘后開始清理子線程后退出。現在想改成子線程啟動后主線程進入無限睡眠,直到收到SIGTERM或SIGINT。主程序如下:
            其他頭文件
            #include <signal.h> //信號處理所需要的頭文件
            int main(int argc, char * argv[]){
              //其他所需要的變量聲明  
              sigset_t sig_set,sig_pending;


              // 設置信號阻塞
              sigemptyset(&sig_set);
              sigaddset(&sig_set,SIGTERM);
              sigaddset(&sig_set,SIGINT);
              sigprocmask(SIG_BLOCK,&sig_set,NULL);


              啟動幾個子線程  
              ...........

              // 設置信號阻塞
              sigemptyset(&sig_set);
              sigaddset(&sig_set,SIGTERM);
              sigaddset(&sig_set,SIGINT);
              sigprocmask(SIG_BLOCK,&sig_set,NULL);
             
              //主線程進入睡眠,等待信號到達后跳出睡眠  
              while(1){
                      sigpending(&sig_pending);
                      if(sigismember(&sig_pending, SIGTERM)||
                                sigismember(&sig_pending,SIGINT)){
                            break;
                      }
                      sleep(2);
              }

              //子線程退出情理
              ................
              return 0;

            }

            程序運行后發現 當按下Ctrl+C后程序沒有出現子線程退出時的信息而是立刻退出,非常奇怪。
            仔細分析了一下,發現問題在于忽略了Linux下的多線程模型的特點。

            Linux下的線程實質上是輕量級進程(light weighted process),線程生成時會生成對應的進程控制結構,只是該結構與父線程的進程控制結構共享了同一個進程內存空間。 同時新線程的進程控制結構將從父線程(進程)處復制得到同樣的進程信息,如打開文件列表和信號阻塞掩碼等。由于我們是在子線程生成之后修改了信號阻塞掩碼,此刻子線程使用的是主線程原有的進程信息,因此子線程仍然會對SIGINT和SIGTERM信號進行反應,因此當我們用Ctrl+C發出了SIGINT信號的時候,主進程不處理該信號,而子進程(線程)會進行默認處理,即退出。子進程退出的同時會向父進程(線程)發送SIGCHLD信號,表示子進程退出,由于該信號沒有被阻塞,因此會導致主進程(線程)也立刻退出,出現了前述的運行情況。因而該問題的一個解決方法是在子線程生成前進行信號設置, 或在子線程內部進行信號設置。 由于子線程是往往是一個事務處理函數,因此我建議在簡單的情況下采用前者,如果需要處理的信號比較復雜,那就必須使用后一種方法來處理。這樣,以上的程序邏輯改為如下就可以了:

            #include <signal.h> //信號處理所需要的頭文件
            int main(int argc, char * argv[]){
              //其他所需要的變量聲明  
              sigset_t sig_set,sig_pending;
              啟動幾個子線程  
              ...........

             
              //主線程進入睡眠,等待信號到達后跳出睡眠  
              while(1){
                      sigpending(&sig_pending);
                      if(sigismember(&sig_pending, SIGTERM)||
                                sigismember(&sig_pending,SIGINT)){
                            break;
                      }
                      sleep(2);
              }

              //子線程退出情理
              ................
              return 0;

            }
            文章出處:DIY部落(http://www.diybl.com/course/6_system/linux/Linuxjs/20090317/162211.html)

            亚洲中文字幕伊人久久无码| 天天爽天天狠久久久综合麻豆| 91亚洲国产成人久久精品| 久久精品国产91久久综合麻豆自制| 亚洲国产精品婷婷久久| 亚洲七七久久精品中文国产| 国产精品久久久久久福利69堂| 久久久久99精品成人片三人毛片 | 国产精品欧美久久久天天影视| 国产精品综合久久第一页 | 麻豆精品久久精品色综合| 久久天天躁狠狠躁夜夜av浪潮| 狠狠色丁香久久婷婷综合五月| 久久精品亚洲乱码伦伦中文| 人妻精品久久久久中文字幕69 | 亚洲精品无码久久久久| 久久国产精品国语对白| 国色天香久久久久久久小说| 老司机午夜网站国内精品久久久久久久久 | 青青国产成人久久91网| 亚洲精品乱码久久久久久蜜桃图片| 99精品伊人久久久大香线蕉| 久久人妻AV中文字幕| 欧美一级久久久久久久大片| 亚洲天堂久久精品| 日本精品久久久久中文字幕8| 无码人妻久久一区二区三区免费| 久久婷婷人人澡人人| 国产精品美女久久久久AV福利| 国产精品久久波多野结衣| 2021久久国自产拍精品| 久久久无码精品亚洲日韩蜜臀浪潮 | 国产精品久久久久久影院| 无码久久精品国产亚洲Av影片| 狠狠综合久久综合88亚洲| 久久精品国产亚洲AV久| 久久受www免费人成_看片中文| 亚洲精品国产自在久久| 亚洲国产天堂久久综合| 国产69精品久久久久观看软件| 97精品国产97久久久久久免费|