为什么使用线程 C 时,指令有时会执行两次

Why is an instruction being sometimes executed twice when using threads C

提问人:Rafik Bouloudene 提问时间:10/21/2023 最后编辑:Brian61354270Rafik Bouloudene 更新时间:10/27/2023 访问量:115

问:

我有以下代码,它基本上创建了两个线程,一个读取一个字符,另一个键入它,直到传递字母 f:

char c;
int att = 1;

void* th_read(void *k){     
    
    do {    
        while(!att);
        printf("type a character : ");
        scanf(" %c",&c);
        att = 0;
        
    }while(c != 'f');
    
    
    exit(0);
}

void* th_write(void *k){    
    
    
    do {    
        while(att);
        printf("character typed is : %c \n",c);
        att = 1;
        
    }while(c != 'f');
    
    
    exit(0);
}

void main(){
    int i;
    pthread_t pth_id[2];
    
    
    pthread_create(&pth_id[0], 0,th_read,NULL);
    printf("Main: reading thread created with id = %ld\n", pth_id[0]);
    
    pthread_create(&pth_id[1], 0,th_write,NULL);
    printf("Main: writing thread created with id= %ld\n",pth_id[1]);
    
    for(i = 0; i < 2; i++) pthread_join(pth_id[i],NULL);
    
    exit(0);
}

我的问题是,当用户键入“f”时,指令有时会执行两次。printf("character typed is : %c \n",c);

例:

enter image description here

C Linux p线程

评论

1赞 dimich 10/21/2023
为什么在线程函数的末尾? 终止整个进程。只需从线程函数返回即可终止线程。exit(0)exit()
1赞 Shawn 10/21/2023
您需要一个互斥锁和一些条件变量来同步您的线程。
1赞 pmacfarlane 10/21/2023
至少有一个线程使用 while 的值未初始化。可能还有许多其他问题 - 像这样在没有互斥锁或信号量或类似的情况下在线程之间共享变量是行不通的。c
2赞 Craig Estey 10/21/2023
while(att);不会太好用。要么做:要么更好:使用基元:并用volatile int att = 1;stdatomic.hwhile (atomic_load(&att));atomic_store(&att, some_value);
3赞 Support Ukraine 10/21/2023
使用共享变量且没有正确同步的多线程可能会以各种奇怪的方式失败。您也许能够找到特定系统上特定行为的解释,但 C 代码不能用于调查正在发生的事情。您必须查看生成的机器代码,并且需要对几个系统事物有专业知识。例如处理器及其管道、缓存系统等。所有这些都不值得你花时间......相反,把时间花在学习如何编写正确的多线程代码上。

答:

0赞 DarkFranX 10/27/2023 #1

这可能是由于共享(全局)变量的未受保护的非原子使用而导致的竞争条件。

我建议你通读整个 https://deadlockempire.github.io/ 系列,这是进入多线程概念的一个很好的起点。