Где моя ошибка при уменьшении семафора?

#arrays #c #semaphore

Вопрос:

Я использую семафоры. У меня есть две темы. Первый поток каждые две секунды выполняет цикл, который создает динамический массив. В начале цикла он создает динамический массив и в конечном итоге удаляет его. С другой стороны, поток должен записывать данные в этот динамический массив, очевидно, при условии, что он уже был создан и что он еще не был удален (т. Е. После создания и до удаления). Я не знаю, как правильно использовать семафоры. Где я делаю что-то не так? Спасибо вам за вашу помощь!

 int *array
int position = 0;
static void *thread_A(void *p_vp_arg)
{

    while (1)
    {
        sem_post(amp;sem);
        array = malloc(1024*sizeof(int));
        /* SOME STUFF HERE */
        sleep(2);
        free(array);
    }
}

static void function_B(...){
    if(sem_trywait(amp;sem)){
        printf("I can write into the arrayn");
        array[position] = variable;
        position  = 1;
    }
}
 

В главную:

 sem_init(amp;sem, 0, 0)
 

Ответ №1:

При замедлении массива, которое вы выполняете sem_post() перед выделением массива, это действительно должно быть после него, с a sem_wait() перед удалением, так как прямо сейчас вы снимаете блокировку и позволяете другому потоку попытаться получить доступ к нему до того, как он будет удален. и вы также можете удалить его, пока другой поток в данный момент записывает данные в массив.

В методе записи я бы переключился на использование sem_wait вместо sem_trywait того, чтобы он сам обрабатывал большую часть ожидания. это если у вас нет конкретной причины для использования sem_trywait

Также не используйте результат sem sem_trywait() или любой другой sem в качестве условия цикла, это может привести к его сбою. вместо этого сделайте

 int result = sem_trywait(amp;sem)
if(result == 0){
    //rest of code
 

он возвращает 0 при успешном выполнении и или код ошибки для чего-либо еще, о чем можно прочитать на странице руководства о конкретных ошибках

Наконец, вы никогда не снимаете блокировку в потоке записи, вам нужно это сделать sem_post() , когда вы закончите с блокировкой, как сейчас вы никогда не снимаете блокировку.

Комментарии:

1. проблема в том, что потоки не используют семафор, как мне бы хотелось. Я бы хотел, чтобы поток A заблокировал семафор во время операции создания и удаления, но это не работает.

2. @ReportFeedback да, именно поэтому, как я уже сказал, не снимайте блокировку sem_post до выделения, освободите ее после, а затем восстановите блокировку sem_wait до того, как освободите массив. Затем он снова будет разблокирован, когда он зациклится и переделает массив