2016-11-16 15 views
1

Im пытается узнать семафоры и как они работают между процессами, поэтому я хотел создать программу, которая печатает в 10 раз строку «abcd» из двух отдельных циклов for(). Один для() содержит строку «ab», а в другой - «cd». Я думал, что код в порядке, но, видимо, его нет. Я был бы признателен, если бы вы могли указать на что-то не так, или если у меня что-то не понято.Семафоры POSIX между дочерними и родительскими процессами

Вот код:

int main(void) 
{ 

int i; 
char *p; 
sem_t *sem; //First semaphore 
sem_t *sem2; //Second semaphore 

//create, initialize semaphores 
sem = sem_open("/semaphore1", O_CREAT, 0644, 1); 
sem2 = sem_open("/semaphore2", O_CREAT, 0644, 1); 

if (fork()) //Child process 
{ 
    for (i=0;i<10;i++) 
    { 
     sem_wait(sem2); //Lock the semaphore 
     for (p="ab"; *p; p++) 
     { 
      write(1, p, 1); 
      usleep(100); 
     } 
     sem_post(sem); //Release the semaphore lock 
    } 
    wait(NULL); 
} 
else //Parent process 
{ 
    for (i=0;i<10;i++) 
    { 
     sem_wait(sem); //Lock the semaphore 
     for (p="cd\n"; *p; p++) 
     { 
      write(1, p, 1); 
      usleep(100); 
     } 
     sem_post(sem2); //Release the semaphore lock 
    } 
} 

//Close the Semaphores 
sem_close(sem); 
sem_unlink("/semaphore1"); 
sem_close(sem2); 
sem_unlink("/semaphore2"); 
return 0; 
} 

И один из выходов:

abcd 
cadb 
cadb 
cadb 
cabd 
cabd 
cabd 
cadb 
cabd 
cadb 
+0

Вы должны инициализировать один из семафоров с нуля, а не как с одной. –

+0

@JonathanLeffler Спасибо! это очень помогло! –

ответ

1

Как отмечено в комментарии, вам необходимо инициализировать первый семафор (переименован sem1 для симметрии с sem2 в код ниже) до 0 вместо 1, чтобы родительский процесс прошел первым.

Замечания о детском и родительском процессах были неуместны (родитель получает ненулевой результат от fork() и поэтому работает в if). Эта версия дает желаемый выход даже без вызовов usleep(). Номинально только один из процессов должен использовать sem_close() и sem_unlink(), но поскольку вы не проверяете или не сообщаете о каких-либо ошибках, вы не замечаете, что вызовы не сработали.

#include <stdio.h> 
#include <semaphore.h> 
#include <unistd.h> 
#include <sys/wait.h> 

int main(void) 
{ 
    int i; 
    char *p; 
    sem_t *sem1; // First semaphore 
    sem_t *sem2; // Second semaphore 

    // create, initialize semaphores 
    sem1 = sem_open("/semaphore1", O_CREAT, 0644, 0); 
    sem2 = sem_open("/semaphore2", O_CREAT, 0644, 1); 

    if (fork()) // Parent process 
    { 
     for (i = 0; i < 10; i++) 
     { 
      sem_wait(sem2); // Lock the semaphore 
      for (p = "ab"; *p; p++) 
      { 
       write(1, p, 1); 
       //usleep(100); 
      } 
      sem_post(sem1); // Release the semaphore lock 
     } 
     wait(NULL); 
    } 
    else // Child process 
    { 
     for (i = 0; i < 10; i++) 
     { 
      sem_wait(sem1); // Lock the semaphore 
      for (p = "cd\n"; *p; p++) 
      { 
       write(1, p, 1); 
       //usleep(100); 
      } 
      sem_post(sem2); // Release the semaphore lock 
     } 
    } 

    // Close the Semaphores 
    sem_close(sem1); 
    sem_unlink("/semaphore1"); 
    sem_close(sem2); 
    sem_unlink("/semaphore2"); 
    return 0; 
} 

Пример вывода:

abcd 
abcd 
abcd 
abcd 
abcd 
abcd 
abcd 
abcd 
abcd 
abcd 
+0

Это тот ответ, который я искал! –