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.运行结果: