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.運行結果: