Значение семафора в функции внутри функции потока не соответствует - PullRequest
2 голосов
/ 13 марта 2019

Я изучаю, как использовать pthreads и мьютексы, и запутался в выводе следующего кода C:

#include <pthread.h>
#include <semaphore.h>
#include <stdio.h>
#include <stdlib.h>

void *TestThread(void *);
void TestFunc();

sem_t mutex;

int main(int argc, char *argv[]) {
    pthread_t tid;
    sem_init(&mutex, 1, 0);
    pthread_create(&tid, NULL, TestThread, NULL);
    pthread_join(tid, NULL);
}

void *TestThread(void *arg) {
    int val;
    sem_getvalue(&mutex, &val);
    printf("value of mutex in Thread function: %d\n", val);
    TestFunc();
    pthread_exit(NULL);
}

void TestFunc() {
    int val;
    sem_getvalue(&mutex, &val);
    printf("value of mutex in function in Thread function: %d\n", val);
}

Затем я собираю это как g++ -lpthread mutexTest.c -o mutexTest и запускаюс ./mutexText, который дает и выводит как

value of mutex in Thread function: 0
value of mutex in function in Thread function: 1754151134

Почему значение мьютекса изменяется в функции, которую я вызываю в потоке?Я как-то потерял ссылку на мьютекс?

1 Ответ

0 голосов
/ 13 марта 2019

Я не знаю, почему ваш код не работает. К сожалению, для нашей нынешней цели ваш код успешно выполняется на моей машине.

До тех пор, пока кто-то еще не отправит правильный ответ, если вы захотите попробовать со мной несколько идей по отладке, мы можем попробовать следующее.

1. Попробуйте воспользоваться предложением @AndrewHenle: «Что возвращает sem_getvalue() в обоих случаях? Если оно возвращает ненулевое значение, что означает errno

Для информации на моем компьютере (Debian GNU / Linux 9, GCC 6.3, Pthreads 2.24) он возвращает ноль, а errno также равен нулю.

2. Попробуйте изменить

sem_t mutex;

до

volatile unsigned char buffer_before_mutex[0x1000];
sem_t mutex;
volatile unsigned char buffer_after_mutex[0x1000];

Причина: если что-то перезаписывает ваш мьютекс в стеке, это может дать ему некоторое свободное пространство для перезаписи вместо того, чтобы уничтожать мьютекс. Даже если это работает (и я подозреваю, что это не будет), это не будет правильно; но это может позволить понять, что не так с вашим кодом.

3. (Мой ответ мог быть заменен комментариями. Я оставляю ответ здесь на тот случай, если его часть окажется полезной.)

...