Форум программистов, компьютерный форум, киберфорум
C/С++ под Linux
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.80/5: Рейтинг темы: голосов - 5, средняя оценка - 4.80
92 / 19 / 4
Регистрация: 11.04.2015
Сообщений: 1,019
Записей в блоге: 1

Multithreading+pipes

05.12.2015, 14:45. Показов 1135. Ответов 10
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Помогите с кодом, пожалуста.

В упражнении два трэда ( write и read ) должны обменяться сообщением через pipes. Read-тред выдает ошибку Bad file descriptor. Не могу понять почему. Вот код и компиляция с выводом:

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
63
64
65
66
#include <stdio.h>
#include <stdlib.h>
 
#include <pthread.h>
#include <unistd.h>
 
void write_func();
void read_func();
 
int fds[2];
 
int main()
{
    pthread_t write_thread,read_thread;
 
    pthread_create (&write_thread, NULL, (void *)&write_func, NULL);
    pthread_create (&read_thread, NULL, (void *)&read_func, NULL);
 
    pthread_join (write_thread, (void*) NULL);
    pthread_join (read_thread, (void*) NULL);   
 
    return 0;
}
 
void write_func()
{
    FILE* stream;
    const char *message="Hello,world! It's pipe!\n";
    int count=5,rtn;
 
    printf("Write started...\n");
    rtn=pipe(fds);
    if(0!=rtn){
        perror("pipe failed");
        exit(EXIT_FAILURE);
    }
            
    close (fds[0]);
    stream = fdopen(fds[1], "w");
    for (;count>0;--count) {
        fprintf (stream, "%s\n", message);
        printf("Write:%s",message);
        fflush (stream);
        sleep (1);
    }       
    close (fds[1]);
    printf("End of write.\n");
}
 
void read_func()
{
    FILE* stream;
    char buffer[1024];
        
    printf("Read started...\n");    
    close (fds[1]);
    stream = fdopen (fds[0], "r");
    if(stream==NULL){
        perror("Read failed");
        exit(EXIT_FAILURE);
    }
    while (!feof (stream) && !ferror (stream) && fgets (buffer, sizeof (buffer), stream) != NULL)
        fputs (buffer, stdout);
    close (fds[0]);
    printf("End of read.\n");
}
Вот компиляция с выводом:

Bash
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
[maxim@localhost Desktop]$ ./Targil12-1 
Write started...
Read started...
Read failed: Bad file descriptor
Segmentation fault (core dumped)
[maxim@localhost Desktop]$ ./Targil12-1 
Write started...
Write:Hello,world! It's pipe!
[maxim@localhost Desktop]$ ./Targil12-1 
Write started...
Read started...
Write:Hello,world! It's pipe!
Read failed: Bad file descriptor
[maxim@localhost Desktop]$ ./Targil12-1 
Write started...
Read started...
Write:Hello,world! It's pipe!
Read failed: Bad file descriptor
[maxim@localhost Desktop]$
0
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
05.12.2015, 14:45
Ответы с готовыми решениями:

Linux pipes(каналы)
#include &lt;string.h&gt; #include &lt;stdlib.h&gt; #include &lt;stdio.h&gt; #include &lt;unistd.h&gt; #define MAX_STRING_LENGTH 255 #define MAX_TOKS...

Тестирование multithreading/multiprocessing программы
Доброго всем времени суток! Есть задача - перемножение матриц на Си под линукс, 2 реализации - multiprocessing и multithreading. Сами...

Multithreading
Модифицировать самое первое задание практики так, чтобы каждая из трех функций исполнялась в своем собственном потоке. Вывод на терминал и...

10
1265 / 979 / 384
Регистрация: 02.09.2012
Сообщений: 3,026
07.12.2015, 14:09
Вынесите создание пайпа из функции write. Скорее всего "читатель" запускается быстрее и естественно читает невалидный дескриптор пайпы. То, что вы видите, что "Writer started" напечаталось быстрее, ничего не значит!!!
1
92 / 19 / 4
Регистрация: 11.04.2015
Сообщений: 1,019
Записей в блоге: 1
07.12.2015, 14:13  [ТС]
grgdvo, хорошо. Скажите, а нужно делать аллокацию памяти? Функция malloc и т.д. ?
0
1265 / 979 / 384
Регистрация: 02.09.2012
Сообщений: 3,026
07.12.2015, 14:34
Под что аллокацию?? под буфер?? Зависит от размера. Пока (1024 байт) вы помещаетесь в стек.
Если этого достаточно для упражнения, то можно и не использовать malloc
1
92 / 19 / 4
Регистрация: 11.04.2015
Сообщений: 1,019
Записей в блоге: 1
07.12.2015, 18:16  [ТС]
Спасибо.
0
 Аватар для bsa916115
51 / 24 / 12
Регистрация: 10.10.2015
Сообщений: 107
10.12.2015, 02:13
Я не догоняю может ночью, но в чем смысл делать close.
Вот man fdopen
the fdopen function assotiates a stream with the existing file descriptor. и т.д.
fdopen не создает новый дескриптор, а использует уже имеющийся.
А Вы ему сразу в начале потока close делаете. Понятное дело, программа в растерянности.
1
92 / 19 / 4
Регистрация: 11.04.2015
Сообщений: 1,019
Записей в блоге: 1
10.12.2015, 08:11  [ТС]
bsa916115, это не обычная программа, которая выполняется последовательно действие за действием. Это мультитрединг, в котором в идеале все треды выполняются процессором одновременно. Но так как до идеала далеко, то каждый тред может прервать любой другой в любой точке. Поэтому надо закрывать поток, в случае если управление перехватил другой тред.

Могу выложить готовый код, вы можете его запустить на линуксе и увидите, что его выполнение раз от раза другое.
0
 Аватар для bsa916115
51 / 24 / 12
Регистрация: 10.10.2015
Сообщений: 107
10.12.2015, 08:32
У Вас pipe - глобальная переменная, которой могут играть все потоки. Если один поток делает close(id), то другой поток уже никак не напишет туда.

Добавлено через 16 минут
Извините, меня прервали. Многопоточность - такая вещь, где надо быть очень осторожным. Если у Вас в данном случае используется fdopen, то он использует глобальный дескриптор. Он в потоке закрывается. Все потоки вроде как делят глобальные переменные. Если в одном потоке дескриптор закрылся, то в другом потоке в него записать нельзя. Вот так как-то.
2
92 / 19 / 4
Регистрация: 11.04.2015
Сообщений: 1,019
Записей в блоге: 1
10.12.2015, 11:07  [ТС]
Помнится у меня без этих close () ошибку core dumped выдавало. Попробую еще раз...
0
1265 / 979 / 384
Регистрация: 02.09.2012
Сообщений: 3,026
11.12.2015, 15:02
все верно bsa916115 говорит.
эти close используются в классических примерах про pipe, но между ПРОЦЕССАМИ != ПОТОКИ,
когда это после fork действительно оправдано.
я не проверял ваш код, но тоже согласен, что надо убрать лишние close
1
92 / 19 / 4
Регистрация: 11.04.2015
Сообщений: 1,019
Записей в блоге: 1
12.12.2015, 16:23  [ТС]
Сейчас проверил. Без этих "лишних" close() выполнение зависает. А с ними работает отлично.

Добавлено через 7 минут
А, прошу прощения. Я этот код переделал и он действительно отлично работает без лишних close()...
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
12.12.2015, 16:23
Помогаю со студенческими работами здесь

Multithreading
Как посчитать время выполнения сложной функции типа void func() в миллисекундах?

Paintcomponent multithreading
Значит разбираюсь сейчас с paintComponent(), и возникла нужда в визуализировании одного процесса, а для этого нужно вынести рисовку в...

boost и Multithreading
Подскажите, пожалуйста, как создать сервер, который принимает запросы от клиентов и отправляет каждый из них в отдельный thread. Вопрос в...

Multithreading: ExecutorService
Кто может подсказать, как работают классы, реализующие данный интерфейс? Например, чем отличается ExecutorService exec =...

Multithreading (монитор) !
Разбирался с монитоорм джавы, пока дело не долшло до deadlock`а. Тут вообще какая-то черная магия) Вот код: Код класса Operation:...


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

Или воспользуйтесь поиском по форуму:
11
Ответ Создать тему
Новые блоги и статьи
Оттенки серого
Argus19 18.03.2026
Оттенки серого Нашёл в интернете 3 прекрасных модуля: Модуль класса открытия диалога открытия/ сохранения файла на Win32 API; Модуль класса быстрого перекодирования цветного изображения в оттенки. . .
SDL3 для Desktop (MinGW): Рисуем цветные прямоугольники с помощью рисовальщика SDL3 на Си и C++
8Observer8 17.03.2026
Содержание блога Финальные проекты на Си и на C++: finish-rectangles-sdl3-c. zip finish-rectangles-sdl3-cpp. zip
Символические и жёсткие ссылки в Linux.
algri14 15.03.2026
Существует два типа ссылок — символические и жёсткие. Ссылка в Linux — это запись в каталоге, которая может указывать либо на inode «файла-ИСТОЧНИКА», тогда это будет «жёсткая ссылка» (hard link),. . .
[Owen Logic] Поддержание уровня воды в резервуаре количеством включённых насосов: моделирование и выбор регулятора
ФедосеевПавел 14.03.2026
Поддержание уровня воды в резервуаре количеством включённых насосов: моделирование и выбор регулятора ВВЕДЕНИЕ Выполняя задание на управление насосной группой заполнения резервуара,. . .
делаю науч статью по влиянию грибов на сукцессию
anaschu 13.03.2026
прикрепляю статью
SDL3 для Desktop (MinGW): Создаём пустое окно с нуля для 2D-графики на SDL3, Си и C++
8Observer8 10.03.2026
Содержание блога Финальные проекты на Си и на C++: hello-sdl3-c. zip hello-sdl3-cpp. zip Результат:
Установка CMake и MinGW 13.1 для сборки С и C++ приложений из консоли и из Qt Creator в EXE
8Observer8 10.03.2026
Содержание блога MinGW - это коллекция инструментов для сборки приложений в EXE. CMake - это система сборки приложений. Здесь описаны базовые шаги для старта программирования с помощью CMake и. . .
Как дизайн сайта влияет на конверсию: 7 решений, которые реально повышают заявки
Neotwalker 08.03.2026
Многие до сих пор воспринимают дизайн сайта как “красивую оболочку”. На практике всё иначе: дизайн напрямую влияет на то, оставит человек заявку или уйдёт через несколько секунд. Даже если у вас. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru