LINUX.ORG.RU

помогите с select/pipe, плииииз...


0

0

Вот такая прога не работает.
Здесь оба потока создаются нормально, один начинает писать в свой файл, сообщая каждую секунду write OK. Однако второй поток вообще ничего не сообщает, вызов select подвисает. Подскажите, плиз, в чем тут дело.

int mypipe[2];

void * start1(void*p)
{
  int i;
  char buf[1];
  int err;
  for(i=0;i<10;++i) {
    sleep(1);
    buf[0] = (char)i;
    if(write(mypipe[1], buf, 1) < 0) {
      perror("thread1: write error:");
      break;
    }    
  }
  return NULL;
}

void * start2(void*p)
{
  int i;
  int err;
  char buf[1];
  fd_set s;
  for(i = 0; i < 15; ++i) {
    FD_ZERO(&s);
    FD_SET(mypipe[0], &s);
    if((err=select(1, &s, NULL, NULL, NULL)) < 0) {
      perror("thread2: file descriptors select error:");
      break;
    }
    else if(err == 0)
      printf("select timeout\n");
    if(read(mypipe[0], buf, 1) < 0) {
      perror("thread2: read error:");
      break;
    }    
    else
      printf("data received: %d\n", buf[0]);
  }    
  return NULL;
}

int main()
{
  pthread_t th1, th2;
  int err;
  
  if((err = pipe(mypipe)) != 0) {
    perror("error creating pipe: ");
    return 1;
  }
  
  pthread_create(&th2, NULL, start2, NULL);
  pthread_create(&th1, NULL, start1, NULL);
  return 0;
}

Если честно я не совсем понял как оно вобще может работать...

pthread_create(&th2, NULL, start2, NULL);

pthread_create(&th1, NULL, start1, NULL);

return 0;

ты создал два потока и вышел из "родителя"

они ведь отомрут сразу же. Это ведь не fork. Да и с fork'ом тоже так нельзя.

И потом разве можно так работать через pipe в thread'ах ?

В общем ты лучше скажи, что ты хочешь сделать.

Dead ★★★★
()

Эээ... да-да, я неправ. Просто у меня был довольно большой файл, а я его подрезал для "читабельности" - и вот бага такая вышла. А с ошибкой я разобрался (первый ответивший anonymous). Вот, а что значит - "И потом разве можно так работать через pipe в thread'ах?" Что я неправильно делаю?

JekLove
() автор топика

Я имел в виду, что взаимодействие между thread'ами редко строится через пайпы. Хотя в общем-то хозяин-барин :-)

Поидее там можно все разрулить через мьютексы и общие данные.

Dead ★★★★
()

Ну я же вот двадцать сообщений назад как раз спрашивал, как мне лучше сделать.... Погляди мой топик :)

JekLove
() автор топика
Ответ на: комментарий от Dead

Dead (*) (2003-02-06 14:35:05.081):
> взаимодействие между thread'ами редко строится через пайпы.

Только потому, что треды, как правило, юзаются народом, не имеющим понятия о том,
что такое пайпы.

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

Die-Hard ★★★★★
()

Очень удобно в потоке использовать select на pipe для команд управления потоком и сокетов для приема/передачи данных по сети. mutex'ы тут не помогут так как они не смогут вывести поток из блокирующего select'а. Данные для команд при этом можно передавать через память для эффективности.

anonymous
()

2Die-Hard >Пайпы могут использоваться не только для передачи больших порций данных (тогда шареная память на мутексах, конечно, эффективнее), но и для обмена сигнальной информацией - тогда пайпы могут быть даже эффективнее семафорной техники.

Оно может и эффективней. Но я бы это сделал так.

Берем один мьютекс и одну общую переменную, в которую записываем сигнал.

Ждем разблокировка мьютекса, как только он разблокирован читаем сигнал из переменной.

Одно только, нельзя таймаут сделать.

Все это только относительно к трэдам одной программы. Если нужна возможность управдения потоками из-вне, то естественно без пайпа не обойтись.

Dead ★★★★
()
Ответ на: комментарий от Dead

Dead (*) (2003-02-07 13:49:31.526):
> Берем один мьютекс и одну общую переменную, в которую записываем сигнал.
> Ждем разблокировка мьютекса, как только он разблокирован читаем сигнал из переменной.

А если я хочу ждать сигнала от 25 тредов сразу?

Ключевая идея мутекса - он MUTUAL exclusion, ВЗАИМНО исключающий, то есть он
предотвращает одновременный доступ к чему-то ДВУХ тредов. Я не представляю себе, как к
помощью семафорной техники соорудить аналог select'а, не плодя по лишнему треду
на каждое вхождение в очереди.



Die-Hard ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.