Семафоры POSIX: проблема синхронизации - PullRequest
3 голосов
/ 03 июня 2011

У меня проблема с синхронизацией с использованием семафоров posix.Вот код, который я написал

sem_t *sem1, *sem2;

void* test1() {
    int rv;

    while(1) {
        rv = sem_wait(sem1);
        printf("sem_wait(&sem1) = %d\n",rv);
        printf("test1\n");

        rv = sem_post(sem2);
        printf("sem_post(&sem2) = %d\n\n",rv);
    }
    return NULL;
}

void* test2() {

    while(1) {

        rv = sem_wait(sem2);
        printf("sem_wait(&sem2) = %d\n",rv);
        printf("test2\n");

        rv = sem_post(sem1);
        printf("sem_post(&sem1) = %d\n\n",rv);
    }
    return NULL;
}

int main (int argc, const char * argv[]) {

pthread_t t1,t2;

sem1 = sem_open("sem1", O_CREAT | O_EXCL, 0644, 1);

if (sem1 == SEM_FAILED){
    perror("sem1_init");
    sem_close(sem1);
    return;
}   

sem2 = sem_open("sem2", O_CREAT | O_EXCL, 0644, 0);
if (sem2 == SEM_FAILED){
    perror("sem2_init");
    sem_close(sem1);
    sem_close(sem2);
    return;
}

pthread_create(&t1, NULL, &test1, NULL);
pthread_create(&t2, NULL, &test2, NULL);

pthread_join(t1, NULL);
pthread_join(t2, NULL);

return 0;
}

Я ожидал, что, поскольку я инициализировал sem1 в 1 и sem2 в 0, test1 будет первой функцией, которая будет запущена, и затем они будутчередовать до конца времени.
Вместо этого он не работает, я имею в виду, что в журнале я много раз читал «test1», много раз «test2», какое-то время чередовался, а затем снова без какого-либо порядка.Может кто-нибудь сказать мне, где моя ошибка?

пс.не знаю, может ли это быть полезно, но я использую MacOSX 10.6.7


РЕДАКТИРОВАТЬ: я обновил свой код, удалив все вызовы sem_init и sem_getvalue (оба отсутствуют вMacOS), используя sem_open для инициализации семафоров, и это, кажется, работает.
Однако я обнаружил странную проблему, возможно, из-за неправильного понимания вызова sem_open: каждый раз, когда я перезапускаю программу, если я повторно использую одно и то же имя для семафоров, я получаю ошибку File exists.Как я могу заставить повторно использовать тот же идентификатор?

Кроме того.согласно справочным страницам, sem_wait должен вернуть 0 в случае успеха, -1 если нет.Что это значит, если я получаю 1 (это всегда происходит в test2)?

1 Ответ

1 голос
/ 04 июня 2011

Если вы хотите чередовать две функции, вы должны просто использовать один семафор.

Когда один из ваших потоков запланирован, например, t1, он блокирует sem1, а затем сохраняет его и работает в цикле while, пока не прервется. Поскольку он не выполняет sem_post (& sem1), он не передает контроль другому потоку.


Обновление: еще раз, этот код должен работать. Я думаю, что sem_init, не внедряемый в OSX, вероятно, является вашей проблемой.


Обновление: чтобы ответить на ваш вопрос о возвращении sem_wait 1, похоже, что реальное значение ошибки возвращается в errno. Если возвращаемое значение != 0, то проверьте там. Мой выстрел в темном догадке будет EINTR, это то, что вы видите.

...