无法异步打印偶数和奇数

时间:2017-09-02 19:36:32

标签: c multithreading pthreads

我想打印主线程中的奇数和新线程中的偶数。我尝试编写程序,但它只打印奇数而不是偶数。我试着寻找线索,找出错误但却找不到任何错误。

这是我的代码。

#include<stdio.h>
#include<stdlib.h>
#include<pthread.h>
#define MAX 1000

int count = 0;

void print_odd_numbers();
void *print_even_numbers();

int main() {
    pthread_t t;
    int iret;
    iret = pthread_create(&t, NULL, print_even_numbers, NULL);
    print_odd_numbers();        
    pthread_join(t, NULL);
    return 0;
}

void print_odd_numbers() {
    while(count <= MAX) {
        if(count % 2 == 1) {
            printf("%d\n", count);
        }
        count++;
    }
}

void *print_even_numbers() {
    while(count <= MAX) {
        if(count % 2 == 0) {
            printf("%d\n", count);
        }
        count++;
    }
    pthread_exit(NULL);
}

2 个答案:

答案 0 :(得分:1)

print_odd_numbersprint_even_numbers增加count的事实,即使它们没有打印任何东西,也是这里麻烦的根源。

count的所有增量都将在print_odd_numbers中生成,count将在MAX开始之前设置为print_even_numbers

使count本地函数可以提供帮助,或者对count递增方式更加谨慎是另一种方式 - 如果你保持其全局性,那么你应该考虑使用原子增量

答案 1 :(得分:0)

如果您不让编译器知道您的计数被多个线程使用,那么它可以完全重新排列您的代码。例如,编译器可能将print_odd_numbers更改为更像

的内容
void print_odd_numbers() {
    if (count <= MAX) {
        if(count % 2 == 1) {
            printf("%d\n", count);
        }
        count++;
    }
    while(count <= MAX) {
        printf("%d\n", count);
        count += 2;
    }
}

此外,每个CPU或核心都将使用它自己的count副本,因为我们拥有所有这些令人敬畏的CPU缓存,可以加快速度。除非你以某种方式让编译器知道其他线程使用了这个内存位置,否则每个线程(如果在它自己的核心上运行)将只使用自己的副本,然后在某些时候将该值写回主内存。

您需要使用原子增量指令或使用互斥锁,关键部分,信号量等保护您的全局。当您使用信号量,互斥量等时,编译器会自动生成LOCK指令(在x86上,或类似于其他archs)迫使CPU在CPU和核心之间以连贯的方式管理其缓存中的内存。

pthreads: If I increment a global from two different threads, can there be sync issues?