多线程下的数据安全 问题

多线程下的数据安全 问题

在unix下如果不加锁使用全局变量会产生数据安全问题,比如,不安全的做法

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 

#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

运行结果并没有像预期的一样:

/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 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 

#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

运行结果:

/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。最终结果显示错乱

你可能感兴趣的:(linux,c)