我想打印主线程中的奇数和新线程中的偶数。我尝试编写程序,但它只打印奇数而不是偶数。我试着寻找线索,找出错误但却找不到任何错误。
这是我的代码。
#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);
}
答案 0 :(得分:1)
print_odd_numbers
和print_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?