2015-10-14 1 views
0

Я пытаюсь разработать приложение для имитатора подъема в C, и для этого я собираюсь использовать как общую память, так и каналы для межпористых коммуникаций. Чтобы сделать мою жизнь немного легче, я объявил две функции: read_from_pipe и write_to_pipe.Не удается правильно связать «ребенка» и «родителя»

Ниже часть моего main кода, который мне нужно выяснить, почему это не так, как ожидалось:

01 #include <stdio.h> 
02 #include <stdlib.h> 
03 #include <string.h> 
04 #include <sys/types.h> 
05 #include <sys/stat.h> 
06 #include <fcntl.h> 
07 #include <sys/mman.h> 
08 
09 #include "windows.h" 
10 
11 #define READ 0 
12 #define WRITE 1 
13 
14 typedef struct lift 
15 { 
16   int winch_control; 
17   int door_control; 
18   int call_buttons; 
19   int lift_buttons; 
20   double position; 
21   double door_ajar; 
22   int quit; 
23   int reset; 
24   int error; 
25 } lift; 
26 int main(void) 
27 { 
28 lift *pLift; 
29 pid_t pid; 
30 off_t off = 0; 
31 int liftfd, mmlen = sizeof(lift), FIFO[2];; 
32 
33 pid = fork(); 
34 liftfd = open("liftfile", (O_CREAT | O_RDWR), 0666); 
35 pLift = (lift *)mmap((caddr_t)0, mmlen, (PROT_READ | PROT_WRITE), MAP_SHARED, liftfd, off); 
36 
37 if (pipe(FIFO))     // create pipe failed 
38 { 
39  fprintf(stderr, "Pipe failed.\n"); 
40  return EXIT_FAILURE; 
41 } 
42 
43 if (pid == (pid_t)0)   // child process 
44 { 
45  close(FIFO[WRITE]);   
46  read_from_pipe(FIFO[READ]); 
47  close(FIFO[READ]); 
48 } 
49 else if (pid < (pid_t)0)  // create fork failed 
50 { 
51  fprintf(stderr, "Fork failed.\n"); 
52  return EXIT_FAILURE; 
53 } 
54 else       // parent process 
55 { 
56  close(FIFO[READ]);   
57  write_to_pipe(FIFO[WRITE],"UP3" , 56); 
58  close(FIFO[WRITE]); 
59 } 
60 } 

read_from_pipe подпрограмма:

void read_from_pipe(int fileDescriptr) 
{ 
    FILE *stream; 
    int c; 
    stream = fdopen(fileDescriptr, "r"); 
    while ((c = fgetc(stream)) != EOF) 
     putchar(c); 
    fclose(stream); 
} 

write_to_pipe подпрограмма:

void write_to_pipe(int fileDescriptr , char *stateName , int timerValue) 
{ 
    FILE *stream; 
    stream = fdopen(fileDescriptr, "w"); 
    fprintf(stream, "Current system state:\t%s\n", stateName); 
    fprintf(stream, "Timer value:\t\t%d\n",timerValue); 
    fflush(stream); 
    fclose(stream); 
} 

Пара вещей, которые я wo uld нравится указывать:

  • Я поместил номера строк в случае, если кто-то хочет обратиться к определенной строке . Я предполагаю, что все знают, как использовать режим столбца в редакторе и удалять их для успешной компиляции.
  • Множество вещей в коде могут выглядеть излишними сначала, но они фактически используются в другом месте кода. Поэтому игнорируйте избыточность , если вы выбрали какой-либо.
  • Я использую CygWin для Windows.

По строке номер 57 мой ожидаемый результат был:

Current system state:  UP3 
Timer value:    56 

Однако я получаю пустой экран.

Любая идея, что я делаю неправильно?

ответ

1

после вызова fork() есть 3 Каковы возможности

1) возвращаемое значение < 0, что указывает на вилку() не удалось

2) возвращаемое значение равно 0, указывающий ребенок выполняет

3) возвращаемое значение> 0 указывает, что родитель выполняет.

Предполагая, что произошел сбой, родительский и дочерний объекты выполняют код, следующий за вызовом fork(). поэтому и родитель, и ребенок звонят open() и mmap().

Необходимо проверить, что возвращаемое значение из open() и из mmap() должно быть проверено для обеспечения успешной работы (операций).

mmap() results не используются в тексте сообщения.

Результаты open() не используются в тексте сообщения.

Линия: fprintf(stderr, "Fork failed.\n");, вероятно, должна быть вызвана perror(), поэтому также отображается системное сообщение об ошибке.

корень проблемы, похоже, состояние гонки.

предлагаю использовать read(), а не fgetc(), так как чтение будет ждать нужного количества символов, так что дождитесь, пока данные будут доступны. Обязательно проверьте возвращаемое значение от read() и повторите попытку в цикле до тех пор, пока возвращаемое значение не будет 0 (или при ошибке меньше 0)

+0

Вы были правы. Я поместил все в 'else' после' pipe() 'call, и это сработало! – Bababarghi