У меня есть следующий код:
#include <stdio.h>
#include <unistd.h>
#include <pthread.h>
char condA = 0;
volatile int vA = 0;
volatile int vB = 0;
void* thread_a(void* arg) {
while (1) {
if (1 == condA) {
vA += 1;
usleep(100);
} else {
;
// vB += 1;
// usleep(100);
}
}
return NULL;
}
void* thread_b(void* arg) {
condA = 1;
return NULL;
}
int main(void) {
pthread_t threadA;
pthread_t threadB;
if (0 != pthread_create(&threadA, NULL, thread_a, NULL)) {
return -2;
}
sleep(1);
if (0 != pthread_create(&threadB, NULL, thread_b, NULL)) {
return -1;
}
pthread_join(threadB, NULL);
sleep(1);
pthread_cancel(threadA);
printf("value A is %d\n", vA);
printf("value B is %d\n", vB);
return 0;
}
Я запускаю свой g cc 5.4.0 с -O0 и -O1.
На O0 вывод: значение A равно 501
На O1 вывод: значение A равно 0
Я знаю, что установка condA
на volatile исправит это, но почему это так? Почему компилятор оптимизирует условие, если оно явно задано в другом потоке?
Кроме того, если я раскомментирую код в операторе else, он будет работать, как и ожидалось.
Частичный ответ I найдено: https://gcc.gnu.org/onlinedocs/gcc-5.4.0/gcc/Volatiles.html#Volatiles "C имеет концепцию энергозависимых объектов. Обычно к ним обращаются указатели и они используются для доступа к аппаратным средствам или связи между потоками. [...]"
Но это не объясняет того факта, что если я раскомментирую код в операторе else, программа будет работать с -O1.