переменная в стеке вызовов неожиданно изменилась c - PullRequest
1 голос
/ 24 марта 2020

Используя потоки c11, я пытаюсь убедиться, что foo является потокобезопасным. В то время как foo не реентерабелен, я пытаюсь смягчить это с помощью мьютексов.

Я не понимаю, почему значение thrdn изменяется в критическом l oop. Насколько я понимаю, каждый поточный вызов foo будет иметь свою собственную версию thrdn, но кажется, что во время выполнения он изменяется другими потоками.

Я пытался переместить mtx_lock выше объявления thrdn и изменение thrdn на тип atomic_int *, однако оба они приводят к одному и тому же поведению.

#include <stdio.h>
#include <threads.h>
#include <string.h>
#include <stdlib.h>

#define THREAD_MAX 5

thrd_t threads[THREAD_MAX];
mtx_t mtx;

void foo(void * data)
{
        int* thrdn = (int *)data;

        mtx_lock(&mtx);
        for(int i = 0; i < 3; ++i) {
                printf("thread %d, number %d\n", *thrdn, i);
        }
        mtx_unlock(&mtx);
}

int main()
{
        mtx_init(&mtx, mtx_plain | mtx_recursive);
        for(int i = 0; i < THREAD_MAX; ++i){
                thrd_create(&threads[i], foo, &i);
        }

        for(int i = 0; i < THREAD_MAX; ++i){
                thrd_join(threads[i], NULL);
        }
        mtx_destroy(&mtx);
}

1 Ответ

0 голосов
/ 24 марта 2020

Как было отмечено в комментариях, проблема заключалась в ссылке на локальную переменную i. Идентификаторы цепочек отслеживания отдельно, как показано в , этот ответ решил проблему.

...