多线程下的数据安全 问题
在unix下如果不加锁使用全局变量会产生数据安全问题,比如,不安全的做法
#include <unistd.h>
#include <stdio.h>
#include <net/if.h>
#include <stdlib.h>
#include <string.h>
#include <stropts.h>
#include <sys/ioctl.h>
#include <errno.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <net/route.h>
#include <sys/types.h>
#include <pthread.h>
#define NLOOP 5
int counter=0;
//pthread_mutex_t counter_mutex = PTHREAD_MUTEX_INITIALIZER;
void *doit(void*);
int main(int argc,char **argv)
{
pthread_t tidA,tidB;
pthread_create(&tidA,NULL,&doit,NULL);
pthread_create(&tidB,NULL,&doit,NULL);
pthread_join(tidA,NULL);
pthread_join(tidB,NULL);
exit(0);
}
void *doit(void *vptr)
{
int i,val;
for(i = 0;i<NLOOP;i++)
{
// pthread_mutex_lock(&counter_mutex);
printf("(thread)%lu:%d\n",pthread_self(),counter+1);
counter = counter+1;
// pthread_mutex_unlock(&counter_mutex);
}
return NULL;
}
运行结果并没有像预期的一样:
/test1/cmake-build-debug/xing2233 inet4 0
(thread)140467018442496:1
(thread)140467018442496:2
(thread)140467018442496:3
(thread)140467018442496:4
(thread)140467018442496:5
(thread)140467026835200:1
(thread)140467026835200:7
(thread)140467026835200:8
(thread)140467026835200:9
(thread)140467026835200:10
Process finished with exit code 0
如果我们使用互斥锁就可以解决:
#include <unistd.h>
#include <stdio.h>
#include <net/if.h>
#include <stdlib.h>
#include <string.h>
#include <stropts.h>
#include <sys/ioctl.h>
#include <errno.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <net/route.h>
#include <sys/types.h>
#include <pthread.h>
#define NLOOP 5
int counter=0;
pthread_mutex_t counter_mutex = PTHREAD_MUTEX_INITIALIZER;
void *doit(void*);
int main(int argc,char **argv)
{
pthread_t tidA,tidB;
pthread_create(&tidA,NULL,&doit,NULL);
pthread_create(&tidB,NULL,&doit,NULL);
pthread_join(tidA,NULL);
pthread_join(tidB,NULL);
exit(0);
}
void *doit(void *vptr)
{
int i,val;
for(i = 0;i<NLOOP;i++)
{
pthread_mutex_lock(&counter_mutex);
printf("(thread)%lu:%d\n",pthread_self(),counter+1);
counter = counter+1;
pthread_mutex_unlock(&counter_mutex);
}
return NULL;
}
运行结果:
/test1/cmake-build-debug/xing2233 inet4 0
(thread)140137220212480:1
(thread)140137220212480:2
(thread)140137220212480:3
(thread)140137220212480:4
(thread)140137211819776:5
(thread)140137211819776:6
(thread)140137211819776:7
(thread)140137211819776:8
(thread)140137211819776:9
(thread)140137220212480:10
Process finished with exit code 0
错误出现的原因:
线程A运行,把counter的值装载到一个寄存器
系统把线程A切换到线程B。A的寄存器被保存,B的寄存器则被恢复
线程B执行与表达式counter++相对应的5条指令,把新值存储到conn
过一段时间线程B却换回A,A的寄存器被恢复,A从原来的地方继续执行,把寄存器的值counter递加,然后存入conn。最终结果显示错乱