Странное поведение приложения сигналов pthread и posixLinux

Ответить
Anonymous
 Странное поведение приложения сигналов pthread и posix

Сообщение Anonymous »

У меня возникли проблемы с пониманием поведения следующего приложения.
Существует 3 потока:
  • рабочий поток с бесконечным циклом, который блокирует мьютекс, изменяет глобальную переменную, но в конце приводит ее к тому же значению, а затем разблокирует мьютекс.
  • поток супервизора с бесконечным циклом, который каждую секунду блокирует мьютекс. мьютекс, печатает глобальную переменную, затем разблокирует поток прерывания мьютекса
  • с помощью бесконечного цикла, который каждую секунду отправляет сигнал 10 рабочему потоку; обработчик сигнала увеличивает глобальную переменную
Я пробовал это на своей машине, используя wsl2 со всеми комбинациями Ubuntu 22 и 24, gcc-10, gcc-11 и gcc-13. Результат более или менее предсказуем, т.е.
superviser 1
superviser 2
superviser 3
superviser 4
superviser 5

Однако, когда я компилирую его на 128-ядерном сервере под управлением Ubuntu 22 с gcc-10, я получаю странный результат, например:
superviser 1
superviser 1
superviser 1
superviser 1
superviser 1
superviser 1
superviser 1
superviser 2
superviser 2
superviser 2
superviser 2

Еще одно наблюдение: если я перенесу локальный «i» из thread_worker в глобальную переменную, то результат будет ожидаемым, как на моем локальном компьютере.
Можете ли вы помочь мне понять, что на самом деле происходит?
#define _GNU_SOURCE
#include
#include
#include
#include
#include

typedef unsigned int uint32;

static volatile uint32 value = 0;
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
pthread_t t1,t2,t3;

void sighandler(int signal)
{
value++;
}

void* thread_superviser(void* ptr)
{
while(1)
{
pthread_mutex_lock(&mutex);
printf("superviser %d\n", value);
fflush(stdout);
pthread_mutex_unlock(&mutex);
sleep(1);
}
}

void* thread_interrupter(void* ptr)
{
uint32 i,x = 0;
while(1)
{
pthread_kill(t1, 10);
sleep(1);
}
}

void* thread_worker(void* ptr)
{
uint32 i;
while(1)
{
pthread_mutex_lock(&mutex);
for(i = 0; i < 10000; i++)
{
value += i;
}
for(i = 0; i < 10000; i++)
{
value -= i;
}
pthread_mutex_unlock(&mutex);
}
}

int main()
{
signal(10, sighandler);
pthread_create(&t1, NULL, thread_worker, NULL);
pthread_create(&t2, NULL, thread_interrupter, NULL);
pthread_create(&t3, NULL, thread_superviser, NULL);
pthread_join(t1, NULL);
return 0;
}


Подробнее здесь: https://stackoverflow.com/questions/797 ... -behaviour
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «Linux»