寫一個多線程程序在捕捉信號後放在後臺運行(附多線程加鎖的原因見解)

1.在思考這道題的時候首先考慮的是有沒有引入數據,若引入數據必須要加鎖。多線程編程加鎖主要爲了防止多個線程在同一時間訪問同一資源導致導致訪問的不是期望的數據。
例如:
線程thread1訪問全局變量judge:

`void *thread1(void *arg)
 {
 while(1)
   {
         sleep(1);
         judge++;
          printf("%sjudge:%d\n",(char *)arg,judge);  
      }  
   return NULL;
}  `

線程thread2訪問全局變量judge:

`void *thread2(void *arg)
 {
 while(1)
   {
         sleep(1);
         judge++;
          printf("%sjudge:%d\n",(char *)arg,judge);  
      }  
   return NULL;
}  `

如果不加鎖,很有可能線程thread1執行judge++的時候,線程thread2先於thread1執行了一次judge++,導致thread1執行printf的值實際上是judge+2,而不是期望的judge++。
因此,我們要在訪問公共資源之前加鎖,在訪問完公共資源之後解鎖。

2.在加鎖時又要考慮會不會造成死鎖,在剛寫代碼時就遇到這個問題,在一個線程里加兩個鎖不會造成程序編譯鏈接出錯卻會造成程序無法執行。
如下段代碼,兩個鎖,

int  judge=0;
void *thread1(void *arg)
{
    while(1)
    {   
         pthread_mutex_lock(&mut);
         pthread_mutex_lock(&mut);
         printf("%s running! TID:%lu\n",(char *)arg,
           (unsigned long)pthread_self());
         sleep(1);
         judge++;
         pthread_mutex_unlock(&mut);
         pthread_mutex_unlock(&mut);
         printf("%sjudge:%d\n",(char *)arg,judge);
         if (judge >= 65535)  
         {   
           judge = 0;
          }   
      }   
   return NULL;
}

現象:
這裏寫圖片描述

下圖一個線程一個鎖:

void *thread1(void *arg)
{
    while(1)
   {   
        pthread_mutex_lock(&mut);
        printf("%s running! TID:%lu\n",(char *)arg,
           (unsigned long)pthread_self());
        sleep(1);
        judge++;
        pthread_mutex_unlock(&mut);
        printf("%sjudge:%d\n",(char *)arg,judge);
        if (judge >= 65535)  
        {   
           judge = 0;
         }   
     }   
   return NULL;
}

現象:
這裏寫圖片描述
3.寫一個多線程程序在捕捉信號後放在後臺執行的代碼

#include <pthread.h>
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <unistd.h>
#include <signal.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdarg.h>
#include <sys/klog.h>
#include <syslog.h>

pthread_mutex_t     mut;
int  judge = 0;
char Flag_sig = 0;
void *thread1(void *arg)
{
        while(1 != Flag_sig)
        {
            pthread_mutex_lock(&mut);
            printf("%s running! TID:%lu\n",(char *)arg,
                    (unsigned long)pthread_self());
            sleep(1);
            judge++;
            pthread_mutex_unlock(&mut); 
            printf("%sjudge:%d\n",(char *)arg,judge);

            if (judge >= 65535)
            {
               judge = 0;
            }
           return NULL;
         }
}
void *thread2(void *arg)
{
        while(1 != Flag_sig)
       {
          pthread_mutex_lock(&mut);
          printf("%s running! TID:%lu\n",(char *)arg,
                   (unsigned long)pthread_self());
          sleep(1);
          judge++;
          pthread_mutex_unlock(&mut);
          printf("%sjudge:%d\n",(char *)arg,judge);
          if (judge >= 65535)                                                                                      
          {
                judge = 0;

          }
       }
     return NULL;
}
 void *thread3(void *arg)
{
        while(1 != Flag_sig)
        {
          pthread_mutex_lock(&mut);
          printf("%s running! TID:%lu\n",(char *)arg,
                  (unsigned long)pthread_self());
          sleep(1);
          judge++;
          pthread_mutex_unlock(&mut);
          printf("%sjudge:%d\n",(char *)arg,judge);
          if (judge >= 65535)
          {
             judge = 0;
          }
       }
       return NULL;
}

void sig_catch(void)
{
     Flag_sig = 1;
     printf("Program backstage operation\n");
     Flag_sig = 0;
     daemon(0,0);

}

int main(int argc,char **argv)
{
        int          temp;

        pthread_t    tid1;
        pthread_t    tid2;
        pthread_t    tid3;

        signal(SIGINT,(void *)sig_catch);

        if(0 != (temp =  pthread_create(&tid1,NULL,thread1,"thread1")))
        {
                    printf("pthread crceate failed\n");
                    return -1;
        }
        if(0 != (temp =  pthread_create(&tid2,NULL,thread2,"thread2")))
        {
                    printf("pthread crceate failed\n");
                    return -1;
        }
        if(0 != (temp =  pthread_create(&tid3,NULL,thread3,"thread3")))
        {
                    printf("pthread crceate failed\n");
                    return -1;
        }

        while(1)
        {
            sleep(1);
        }
        printf("main TID:%lu\n",(unsigned long)pthread_self());

        return 0;

}

4.運行結果:
這裏寫圖片描述
這裏寫圖片描述

發佈了42 篇原創文章 · 獲贊 16 · 訪問量 5萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章