Форум программистов, компьютерный форум, киберфорум
C/С++ под Linux
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.69/13: Рейтинг темы: голосов - 13, средняя оценка - 4.69
0 / 0 / 0
Регистрация: 18.11.2014
Сообщений: 37

Read in Pipe

20.11.2017, 21:59. Показов 2596. Ответов 8
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Здравствуйте, пишу программу с pipe(). Возникла такая проблема, что в функции receive() возникает зависание. Прошу помочь исправить ошибку. Возникает скорее всего при вызове read(). Данные записанные в sdata, берутся из файлов .h которые нельзя изменять - pa1.h и ipc.h
Заранее спасибо!

C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
//ipc.h
typedef int8_t local_id;
typedef int16_t timestamp_t;
 
enum {
    MESSAGE_MAGIC = 0xAFAF,
    MAX_MESSAGE_LEN = 4096,
    PARENT_ID = 0,
    MAX_PROCESS_ID = 15
};
 
typedef enum {
    STARTED = 0,     ///< message with string (doesn't include trailing '\0')
    DONE,            ///< message with string (doesn't include trailing '\0')
    ACK,             ///< empty message
    STOP,            ///< empty message
    TRANSFER,        ///< message with TransferOrder
    BALANCE_HISTORY, ///< message with BalanceHistory
    CS_REQUEST,      ///< empty message
    CS_REPLY,        ///< empty message
    CS_RELEASE       ///< empty message
} MessageType;
 
typedef struct {
    uint16_t     s_magic;        ///< magic signature, must be MESSAGE_MAGIC
    uint16_t     s_payload_len;  ///< length of payload
    int16_t      s_type;         ///< type of the message
    timestamp_t  s_local_time;   ///< set by sender, depends on particular PA:
                                 ///< physical time in PA2 or Lamport's scalar
                                 ///< time in PA3
} __attribute__((packed)) MessageHeader;
 
enum {
    MAX_PAYLOAD_LEN = MAX_MESSAGE_LEN - sizeof(MessageHeader)
};
 
typedef struct {
    MessageHeader s_header;
    char s_payload[MAX_PAYLOAD_LEN]; ///< Must be used as a buffer, unused "tail"
                                     ///< shouldn't be transfered
} __attribute__((packed)) Message;
C
1
2
3
4
5
6
//pa1.h
static const char * const log_done_fmt =
    "Process %1d has DONE its work\n";
 
static const char * const log_received_all_done_fmt =
    "Process %1d received all DONE messages\n";

C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
int receive(void *self, local_id from, Message *msg)//read 1 message
{   
 
Message msg = {.s_header={.s_magic=MESSAGE_MAGIC}};
msg.s_header.s_payload_len = MAX_PAYLOAD_LEN;/*len*/
//msg.s_header.s_type = /*type*/
time_t ttime;
time(&ttime);
msg.s_header.s_local_time = 0;//ctime(&ttime);/*time*/
 
///////////////
//pipe
///////////////
int fpipe[2];
if(pipe(fpipe)<0)
{
    printf("Cant create pipe!\n");
    exit(1);
    }   
    char sdata[4]={msg->s_header.s_magic,msg->s_header.s_payload_len,msg->s_header.s_local_time,(char)log_done_fmt};
    int dataproc;
    char buffer[4];
printf("%d\n",15);
    dataproc=read(fpipe[0],buffer,14);
printf("%d\n",16);
close(fpipe[0]);
 
        /////////////////////////////////
        //открыть файл events.log
        /////////////////////////////////
        FILE * f2; 
      
        f2 = fopen(events_log, "a");
        if (f2==NULL)
            perror("Ошибка открытия файла");
        else
            {
       printf("файл %s открыт для записи\n",events_log);
    MessageType mt=DONE;
    fprintf(f2,"%hu %hu %hu %u \n",(unsigned short int)msg->s_header.s_magic,(unsigned short int)msg->s_header.s_payload_len,
    (unsigned short int)msg->s_header.s_local_time,(short int)mt);
    }
        fclose(f2);
        
        /////////////////////////////////
        //открыть файл pipes.log
        /////////////////////////////////
        FILE *f1;
        f1 = fopen(pipes_log, "a");
        if (f1==NULL)
            perror("Ошибка открытия файла");
        else
            {
       printf("файл %s открыт\n",pipes_log);  
       fputs("R-open desc f2 file events\n",f1);
       fputs("R-close desc f2 file events\n",f1);                    
       fputs("R-open desc f1 file pipes\n",f1);
       fputs("R-close desc f1 file pipes\n",f1);  
    }
        fclose(f1);
    return from;
}
0
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
20.11.2017, 21:59
Ответы с готовыми решениями:

Отправка сообщений между дочерними и родительским процессами (fork,pipe,write,read)
Здравствуйте, помогите реализовать отправку сообщений по следующей схеме: Попытался самостоятельно реализовать первую схему, вот что...

В чем отличие read от read-line
Подскажите чем отличается read от read-line.

Commited read vs repeatable read
Не могу понять как repeatable read защищается от неповторяющегося чтения. По сути в Commited read блокируется транзакция , а другая ждет...

8
 Аватар для COKPOWEHEU
4083 / 2681 / 432
Регистрация: 09.09.2017
Сообщений: 11,922
21.11.2017, 11:12
Цитата Сообщение от ilia53v Посмотреть сообщение
char sdata[4]={msg->s_header.s_magic,msg->s_header.s_payload_len,msg->s_header.s_local_time,(char)log_done_fm t};
Magic у вас 2 байта а вы пытаетесь запихнуть в char. Тем более что это не константа. Именно этот кусок у вас точно работает? Сделайте отладочный вывод чтобы проверить.
Цитата Сообщение от ilia53v Посмотреть сообщение
int fpipe[2];
if(pipe(fpipe)<0)
{
printf("Cant create pipe!\n");
exit(1);
}
char sdata[4]={msg->s_header.s_magic,msg->s_header.s_payload_len,msg->s_header.s_local_time,(char)log_done_fm t};
int dataproc;
char buffer[4];
printf("%d\n",15);
dataproc=read(fpipe[0],buffer,14);
printf("%d\n",16);
close(fpipe[0]);
А где у вас запись в канал? Похоже что read просто ждет пока хоть что-нибудь не придет. Если не хотите ждать, открывайте в неблокирующем режиме pipe(fpipe, O_NONBLOCK)
0
0 / 0 / 0
Регистрация: 18.11.2014
Сообщений: 37
21.11.2017, 12:08  [ТС]
Вот так выглядит запись в канал
C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
int send(void *self, local_id dst, const Message *msg)//write 1 message in pipe
{           
///////////////
//pipe
///////////////
int all;
all=5;
int fpipe[2];
if(pipe(fpipe)<0)
{
    printf("Cant create pipe!\n");
    exit(1);
    }
    char sdata[4]={msg->s_header.s_magic,msg->s_header.s_payload_len,msg->s_header.s_local_time,(char)log_started_fmt};
    int dataproc;
    dataproc=write(fpipe[1],sdata,strlen(sdata));
        close(fpipe[1]);
}
Добавлено через 8 минут
И что Вы имеете ввиду под отладочным выводом? Проверял с помощью printf, после printf("%d\n",15) программа виснет.
0
 Аватар для COKPOWEHEU
4083 / 2681 / 432
Регистрация: 09.09.2017
Сообщений: 11,922
21.11.2017, 12:21
То есть в разных функциях идет запись в один канал и чтение из другого? Если бы вы использовали именованный канал с доступом по имени была бы другая ситуация.
0
0 / 0 / 0
Регистрация: 18.11.2014
Сообщений: 37
21.11.2017, 12:36  [ТС]
Спасибо, что сказали - вынес pipe в функцию запускающую send(), receive(). Все работает.
0
 Аватар для COKPOWEHEU
4083 / 2681 / 432
Регистрация: 09.09.2017
Сообщений: 11,922
21.11.2017, 13:00
Похоже что у вас однопоточная программа. Зачем там каналы?
0
0 / 0 / 0
Регистрация: 18.11.2014
Сообщений: 37
21.11.2017, 13:23  [ТС]
Процесс-родитель должен породить несколько потоков(процессов) с помощью fork(), pipe нужен чтобы обмениваться сообщениями между созданными потоками. Плюс к этому они должны общаться через pipe с процессом-родителем.

Добавлено через 10 минут
Вы случайно не знаете как можно сделать общение через pipe между процессами-потомками?
0
 Аватар для COKPOWEHEU
4083 / 2681 / 432
Регистрация: 09.09.2017
Сообщений: 11,922
21.11.2017, 13:48
ilia53v, У меня есть похожая задача, правда не с процессами а с потоками. Там это попроще, общее адресное пространство, общая память.
Точного решения дать не могу, но можно попробовать сразу в родителе создать все нужные пары дескрипторов и раздать их потомкам при создании. Или создавать внутри потомка и передавать дескрипторы через канал родителя.
0
0 / 0 / 0
Регистрация: 18.11.2014
Сообщений: 37
21.11.2017, 13:55  [ТС]
Нельзя использовать общее адресное пространство, общую память. К тому же такая программа у меня есть.

Добавлено через 1 минуту
Спасибо за вариант решения.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
21.11.2017, 13:55
Помогаю со студенческими работами здесь

Как Вам фраза read/clear (rc_w1) Software can read as well as clear this bit by writing 1. Writing ‘0’ has no effect on
Как Вам фраза из списка аббревиатур STM32, то есть, чтоб сбросить в ноль бит надо записать туда единицу, гениально. А если Вы запишите туда...

Pipe
Напишите пожалуйста код программы с функцией pipe.

Broken pipe
Narod, help! Chto eto za oshibka? i kak eje pravit'

Чтение из pipe
Имеется испонимый файл (консольное приложение), выводящий, например, &quot;Hello? world!&quot; Требуется из консольного приложения запустить...

Работа с Pipe
Здравствуйте, пытаюсь создать именованный канал, но CreateFile() == INVALID_HANDLE_VALUE, а GetLastError() возвращает 2. Подскажите, в чем...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
9
Ответ Создать тему
Новые блоги и статьи
Как дизайн сайта влияет на конверсию: 7 решений, которые реально повышают заявки
Neotwalker 08.03.2026
Многие до сих пор воспринимают дизайн сайта как “красивую оболочку”. На практике всё иначе: дизайн напрямую влияет на то, оставит человек заявку или уйдёт через несколько секунд. Даже если у вас. . .
Модульная разработка через nuget packages
DevAlt 07.03.2026
Сложившийся в . Net-среде способ разработки чаще всего предполагает монорепозиторий в котором находятся все исходники. При создании нового решения, мы просто добавляем нужные проекты и имеем. . .
Модульный подход на примере F#
DevAlt 06.03.2026
В блоге дяди Боба наткнулся на такое определение: В этой книге («Подход, основанный на вариантах использования») Ивар утверждает, что архитектура программного обеспечения — это структуры,. . .
Управление камерой с помощью скрипта OrbitControls.js на Three.js: Вращение, зум и панорамирование
8Observer8 05.03.2026
Содержание блога Финальная демка в браузере работает на Desktop и мобильных браузерах. Итоговый код: orbit-controls-threejs-js. zip. Сканируйте QR-код на мобильном. Вращайте камеру одним пальцем,. . .
SDL3 для Web (WebAssembly): Синхронизация спрайтов SDL3 и тел Box2D
8Observer8 04.03.2026
Содержание блога Финальная демка в браузере. Итоговый код: finish-sync-physics-sprites-sdl3-c. zip На первой гифке отладочные линии отключены, а на второй включены:. . .
SDL3 для Web (WebAssembly): Идентификация объектов на Box2D v3 - использование userData и событий коллизий
8Observer8 02.03.2026
Содержание блога Финальная демка в браузере. Итоговый код: finish-collision-events-sdl3-c. zip Сканируйте QR-код на мобильном и вы увидите, что появится джойстик для управления главным героем. . . .
Реалии
Hrethgir 01.03.2026
Нет, я не закончил до сих пор симулятор. Эта задача сложнее. Не получилось уйти в плавсостав, но оно и к лучшему, возможно. Точнее получалось - но сварщиком в палубную команду, а это значит, в моём. . .
Ритм жизни
kumehtar 27.02.2026
Иногда приходится жить в ритме, где дел становится всё больше, а вовлечения в происходящее — всё меньше. Плотный график не даёт вниманию закрепиться ни на одном событии. Утро начинается с быстрых,. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru