Модераторы: xvr
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Передача стринга через pipe 
V
    Опции темы
olegsml
Дата 12.8.2009, 00:29 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 7
Регистрация: 12.8.2009

Репутация: нет
Всего: нет



Здравствуйте! 
Пытаюсь передать стринг между двумя дочерними процессами. ниже листинги программ. В чем проблема? на линуксе недавно программирую. 
pipe.c
#include<sys/types.h>
#include<unistd.h>
#include<stdio.h>
#include<string.h>
int main( int argc, char *argv[], char *envp)
{
  int fd[2], result, result1;
  char resstring[14];
  if (pipe<0)
    {
       printf("Can't creat pipe\n");
       exit(-1);
    }
  result=fork();
  if (result<0)
    {
       printf("Can't fork child1\n");
       exit(-1);
    }
  else if (result==0)
    {
       result1=fork();
       if (results1<0)
         {
           printf("Can't fork child2\n");
           exit(-1);
          }
       else if (result==0)
                 {
                    execle("root/child2","root/child2",0,envp);
         }
        else
                {
                    printf("This is child1\n");
            close(fd[1]);
            size=read(fd[0],resstring,14);
            if (size!=14)
            {
               printf("Can't read all string\n");
               exit(-1);
            }
           close(fd[0]);
           printf("%s",resstring);
        }
      }
  else
     {
        printf("This is parent\n");
    exit(-1);
     }
  return 0;
}

child2.c
#include<sys/types.h>
#include<unistd.h>
#include<stdio.h>
#include<string.h>
int main( i)
{
  int fd[2];
  size_t size;
  char resstring[14]={"HELLO, WORLD!"};
  close(fd[0);
  size=write(fd[1],resstring,14);
  if (size!=14)
    {
    printf("Can't write all string\n");
    exit(-1);
     }
  close(fd[1]);
  return 0;
}
При запуске выдает сообщения:
This is child2
Can't write string
This is child1
This is parent
Can't read all string
PM MAIL   Вверх
andrew_121
Дата 12.8.2009, 01:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Кодофей
****


Профиль
Группа: Завсегдатай
Сообщений: 3448
Регистрация: 3.1.2008

Репутация: 3
Всего: 33



Добавлено @ 01:31
Цитата(olegsml @  12.8.2009,  00:29 Найти цитируемый пост)
close(fd[0);

опечатка
что за дескриптор fd[0] ?

Цитата(olegsml @  12.8.2009,  00:29 Найти цитируемый пост)
size=write(fd[1],resstring,14);

что за дескриптор fd[1] ?

Цитата(olegsml @  12.8.2009,  00:29 Найти цитируемый пост)
  if (pipe<0)

кто такой pipe ?

Ты для начала код откомпилируй.

Цитата(olegsml @  12.8.2009,  00:29 Найти цитируемый пост)
При запуске выдает сообщения:
This is child2
Can't write string
This is child1
This is parent
Can't read all string 

странно это все. должен выдать сигфаулт.
он даже компилироваться не должен. Первый точно не скомпилиться.

Это сообщение отредактировал(а) andrew_121 - 12.8.2009, 01:36


--------------------
Удалил аккаунт. Прощайте!
PM MAIL   Вверх
olegsml
Дата 12.8.2009, 11:04 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 7
Регистрация: 12.8.2009

Репутация: нет
Всего: нет



Извиняюсь действительно при подачи листинга программы допустил ошибки, а в программе стоят if(pipe(fd<0) и close(fd[0]). программы компилируются и при запуске создаться два дочерних процесса,  а вот передачи стринга не происходит.
PM MAIL   Вверх
andrew_121
Дата 12.8.2009, 11:58 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Кодофей
****


Профиль
Группа: Завсегдатай
Сообщений: 3448
Регистрация: 3.1.2008

Репутация: 3
Всего: 33



olegsml, Поправь исходный код. И заключи его в теги "
Код
...
", это первое.
Второе. Ты используешь дескрипторы:
Цитата(olegsml @  12.8.2009,  00:29 Найти цитируемый пост)
int fd[2];

но я не вижу чтоб ты их проинициализировал.


--------------------
Удалил аккаунт. Прощайте!
PM MAIL   Вверх
olegsml
Дата 12.8.2009, 12:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 7
Регистрация: 12.8.2009

Репутация: нет
Всего: нет



а зачем дескрипторы инициализировать? в аналогичной программе передачи стринга между родителем и сыном использую декларацию int fd[2] и все работает 
PM MAIL   Вверх
xvr
Дата 12.8.2009, 12:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 7046
Регистрация: 28.8.2007
Где: Дублин, Ирландия

Репутация: 20
Всего: 223



Цитата(olegsml @ 12.8.2009,  12:08)
а зачем дескрипторы инициализировать? 

 smile 
Цитата

в аналогичной программе передачи стринга между родителем и сыном использую декларацию int fd[2] и все работает
А я тут на заборе int fd[2] написал, а ничего за забором не появилось - шайтан!
Сын от родителя fork'ом получен? Тогда и fd он унаследовал от родителя. exec'же стирает ВСЕ, что было у родителя (включая fd), и сын начинает жизнь с 'чистого листа'. Дескрипторы надо передавать не через память (и уж тем более не через абсолютно разные переменные даже если они и называются одинаково  smile )


PM MAIL   Вверх
olegsml
Дата 12.8.2009, 13:00 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 7
Регистрация: 12.8.2009

Репутация: нет
Всего: нет



вместо того что бы забором пугать, взял бы и привел пример как связать эти дескрипторы
PM MAIL   Вверх
xvr
Дата 12.8.2009, 13:31 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 7046
Регистрация: 28.8.2007
Где: Дублин, Ирландия

Репутация: 20
Всего: 223



Цитата(olegsml @ 12.8.2009,  13:00)
вместо того что бы забором пугать, взял бы и привел пример как связать эти дескрипторы

Например передать как параметры командной строки. 
Вместо этого
Код

execle("root/child2","root/child2",0,envp);
сделать так
Код

{
 char fds[2][16];
 sprintf(fds[0],"%d",fd[0]);
 sprintf(fds[1],"%d",fd[1]);
 execle("root/child2","root/child2",fds[0],fds[1],0,envp);
}
и в child2
Код

int main(int argc, char** argv)
{
  int fd[2];

  fd[0]=atoi(argv[1]);
  fd[1]=atoi(argv[2]);
}


Или делать dup2 их на stdio/stdout (как обычно все и делают)

PM MAIL   Вверх
andrew_121
Дата 12.8.2009, 13:35 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Кодофей
****


Профиль
Группа: Завсегдатай
Сообщений: 3448
Регистрация: 3.1.2008

Репутация: 3
Всего: 33



Цитата(olegsml @  12.8.2009,  13:00 Найти цитируемый пост)
взял бы

Ну... Не нужно так! Вам тут никто ничего не должен! По обходительней пожалуйста smile 


По теме.
Цитата(olegsml @  12.8.2009,  12:08 Найти цитируемый пост)
в аналогичной программе передачи стринга между родителем и сыном использую декларацию int fd[2] и все работает  

Код в студию!


--------------------
Удалил аккаунт. Прощайте!
PM MAIL   Вверх
olegsml
Дата 12.8.2009, 14:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 7
Регистрация: 12.8.2009

Репутация: нет
Всего: нет



я не хотел обидеть, но если все таки обидел то искренно извиняюсь. smile 
большое спасибо за примеры. внес изменения и все заработало. а можно поподробнее с функциями dup2().
пожалуйста код программы для обмена родителя и сына( взят из книги "Основы операционных систем" В.Е. Карпов, К.А. Коньков)
#include<sys/types.h>
#include<unistd.h>
#include<stdio.h>
int main( )
{
  int fd[2], result;
  size_t size;
  char resstring[14];
  
  if (pipe(fd)<0)
    {
       printf("Can't creat pipe\n");
       exit(-1);
    }
  result=fork();
  if (result<0)
    {
       printf("Can't fork child1\n");
       exit(-1);
    }
  else if (result>0)
    {
         close(fd[0]);
         size=write(fd[1],"HELLO, WORLD!",14);
         if (size!=14)
         {
           printf("Can't write all string\n");
           exit(-1);
        }
       close(fd[1]);
       printf("Parent exit\n");
      }
  else
     {
         close(fd[1]);
         size=read(fd[0],resstring,14);
         if (size<0)
         {
           printf("Can't read string\n");
           exit(-1);
        }
       printf("%s\n",resstring);
           close(fd[0]);
     }
  return 0;
}
PM MAIL   Вверх
xvr
Дата 12.8.2009, 16:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 7046
Регистрация: 28.8.2007
Где: Дублин, Ирландия

Репутация: 20
Всего: 223



Цитата(olegsml @ 12.8.2009,  14:27)
а можно поподробнее с функциями dup2().

Можно. В родителе (перед exec) делаешь
Код

close(fd[0]);
dup2(fd[1],1);
в потомке пишешь в stdout (дескриптор 1)
Цитата

пожалуйста код программы для обмена родителя и сына( взят из книги "Основы операционных систем" В.Е. Карпов, К.А. Коньков)
Угу, как я и говорил эдесь fd в потомке были проинициализированны в родителе. Так можно делать, так как при fork память дублируется.
Если же потомок запускается через exec, то так делать нельзя, т.к. при exec память очищается

PM MAIL   Вверх
olegsml
Дата 13.8.2009, 01:47 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 7
Регистрация: 12.8.2009

Репутация: нет
Всего: нет



Цитата(xvr @ 12.8.2009,  16:49)
в потомке пишешь в stdout (дескриптор 1)

можно поподробнее?
PM MAIL   Вверх
xvr
Дата 13.8.2009, 07:39 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 7046
Регистрация: 28.8.2007
Где: Дублин, Ирландия

Репутация: 20
Всего: 223



Цитата(olegsml @ 13.8.2009,  01:47)
Цитата(xvr @ 12.8.2009,  16:49)
в потомке пишешь в stdout (дескриптор 1)

можно поподробнее?

Куда уж подробнее - обычный printf или write(1,...);

PM MAIL   Вверх
olegsml
Дата 13.8.2009, 14:18 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 7
Регистрация: 12.8.2009

Репутация: нет
Всего: нет



Разобрался. Огромное спасибо.
PM MAIL   Вверх
andrew_121
Дата 14.8.2009, 00:28 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Кодофей
****


Профиль
Группа: Завсегдатай
Сообщений: 3448
Регистрация: 3.1.2008

Репутация: 3
Всего: 33



Цитата(olegsml @  13.8.2009,  14:18 Найти цитируемый пост)
Разобрался. Огромное спасибо. 

Пометь тему решенной!


--------------------
Удалил аккаунт. Прощайте!
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С/С++: Программирование под Unix/Linux"
xvr
  • Проставьте несколько ключевых слов темы, чтобы её можно было легче найти.
  • Не забывайте пользоваться кнопкой "Код".
  • Вопросы мобильной разработки тут
  • Телепатов на форуме нет! Задавайте чёткий, конкретный и полный вопрос. Указывайте полностью ошибки компилятора и компоновщика.
  • Новое сообщение должно иметь прямое отношение к разделу форума. Флуд, флейм, оффтопик запрещены.
  • Категорически запрещается обсуждение вареза, "кряков", взлома программ и т.д.

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, xvr.

 
 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Программирование под Unix/Linux | Следующая тема »


 




[ Время генерации скрипта: 0.0554 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.