2016-09-16 3 views
1

У меня есть функция, которая печатает что-то char по char в цикле. То, что я пытаюсь сделать, это синхронизировать родительский и дочерний процессы, чтобы каждый печатал строку без вмешательства другого. Я пытаюсь сделать это с помощью семафоров.parent-child sync с системными v семафорами

это мой код:

int main() { 
    int i, sem; 
    struct sembuf u = {0, 1, 0}; 
    struct sembuf d = {0 -1, 0}; 
    sem = semget(IPC_PRIVATE, 1, 0600); 
    semctl(sem, 0, SETVAL, 1); 

    if (!fork()) { 
     for (i=0;i<10;i++){ 
      semop(sem, &d, 1)) < 0) 
      print_char_by_char("hello\n"); 
      semop(sem, &u, 1); 
     } 



    } else { 
     for (i=0;i<10;i++){ 
      semop(sem, &d, 1); 
      print_char_by_char("world\n"); 
      semop(sem, &u, 1); 
     } 


     semctl(sem, 0, IPC_RMID); 
    } 
    return 0; 
} 

Так что это не работает, отпечатки искажены, и я действительно не знаю, почему. Кроме того, если я положил чек на semop так:

if((x = semop(sem, &down, 1)) < 0) 
    perror("semop"); 

я получаю semop: File too large

ответ

0

Согласно man semop

EFBIG: для некоторой операции значение sem_num меньше 0 или reater или равно числу семафоров в наборе.

Тогда, не зная, как ваша print_char_by_char функции, мы не можем знать, почему вы получаете искаженную печать (помните, что printf и другие буферный, так что вы должны использовать fflush рядом или непосредственно использовать write вместо этого.

Кстати, я попытался выполнить свой код (который я написал ниже), и у меня нет никаких проблем (потому что вы не указали, что выход вы ожидаете), если я удалю

semctl(sem, 0, IPC_RMID); 

что, возможно, вы ошибаетесь (следует g о как раз перед return, в противном случае тот, кто заканчивает первый будет удалить набор семафоров, я думаю)

КОД

#include <stdio.h> 
#include <stdlib.h> 
#include <unistd.h> 
#include <sys/ipc.h> 
#include <sys/types.h> 
#include <sys/sem.h> 

void error_handler(const char *msg) 
{ 
    perror(msg); 
    exit(EXIT_FAILURE); 
} 

int main(int argc, const char **argv) 
{ 
    if (argc != 1) 
    { 
     fprintf(stderr, "Usage: %s <no arguments>\n", argv[0]); 
     return EXIT_FAILURE; 
    } 

    int i, sem; 
    struct sembuf u = {0, 1, 0}; 
    struct sembuf d = {0, -1, 0}; 
    sem = semget(IPC_PRIVATE, 1, 0600); 
    semctl(sem, 0, SETVAL, 1); 

    if (!fork()) 
    { 
     for (i = 0; i < 10; i++) 
     { 
      if (semop(sem, &d, 1) == -1) 
       error_handler("main | semop [d - father]\n"); 
      if (write(STDOUT_FILENO, "hello\n", 7) == -1) 
       error_handler("main | write [hello]\n"); 
      if (semop(sem, &u, 1) == -1) 
       error_handler("main | semop [u - father]\n"); 
     } 
    } else { 
     for (i = 0; i < 10; i++) 
     { 
      if (semop(sem, &d, 1) == -1) 
       error_handler("main | semop [d - child]\n"); 
      if (write(STDOUT_FILENO, "world\n", 7) == -1) 
       error_handler("main | write [world]\n"); 
      if (semop(sem, &u, 1) == -1) 
       error_handler("main | semop [u - child]\n"); 
     } 

     // semctl(sem, 0, IPC_RMID); 
    } 

    return EXIT_SUCCESS; 
} 

ВЫВОД

world 
world 
world 
world 
world 
world 
world 
world 
world 
world 
hello 
hello 
hello 
hello 
hello 
hello 
hello 
hello 
hello 
hello 

Вместо этого, если вы хотите для синхронизации двух процессов в отношениях между отцом и ребенком (это звучит странно ...) Я предлагаю вам разделяемую память и семафоры POSIX