Как можно использовать каналы Unix между основным процессом и потоком? - PullRequest
7 голосов
/ 08 июня 2009

Я пытаюсь направить данные по каналам всякий раз, когда сигнал поступает из потока в основной процесс.

Возможно ли это?
Как это можно сделать?


Проблема:

  1. Дочерний поток читает данные и помещает их в очередь.
  2. Главное приложение выполняет свои функции, однако, когда данные доступны в очереди, они должны уведомить об этом поток и начать обработку данных (основной поток имеет доступ к очереди).

Как реализовать этот сценарий?

Ответы [ 5 ]

13 голосов
/ 08 июня 2009

Да, это возможно через трубы.

Шаг первый вызов труба , чтобы получить трубу:

  #include <unistd.h>


  int main(...)
  {

    int fileDescriptors[2];
    pipe(fileDescriptors);

Шаг 2 передает fileDescriptors [0] в основной процесс, а fileDescriptors 1 в поток. В Main вы ожидаете записи канала, читая из fileDescriptors [0]

    ...
    char msg[100];
    read(fileDescriptors[0], msg, 100);  // block until pipe is read
  }

Шаг 3, из вашего потока пишите в fileDescritpors 1 при возникновении сигнала

 void signal_handler( int sig )
 {
     // Write to the file descriptor
     if (sig == SIGKILL)
     {
         const char* msg = "Hello Mama!";
         write(fileDescriptors[1], msg, strlen(msg));
     }
 }
4 голосов
/ 08 июня 2009

Это можно сделать, но это скорее не нужно. Трубы предназначены для межпроцессного взаимодействия. Потоки совместно используют одну и ту же память и поэтому могут обмениваться данными напрямую, если вы правильно используете блокировку.

1 голос
/ 08 июня 2009

Если вы говорите о pipe(), а не |, тогда да. Трубы, как правило, могут рассматриваться как дескриптор файла. Вам просто нужно открыть канал и очистить вход в одном потоке, а выход в другом.

0 голосов
/ 08 июня 2009

Вы можете сделать это, apache имеет аналогичную опцию «постепенного перезапуска». (см. здесь ). Вы бы использовали что-то вроде:

#include <sys/types.h>
#include <signal.h>

kill(getppid(), SIGUSR1);

Чтобы отправить сигнал родителю. Другие имеют код выше, чтобы порождать файловые дескрипторы и перехватывать его на родительской стороне.

Однако я склонен избегать сигналов для межпроцессного взаимодействия по сценарию, вместо этого использую их только для сообщений, «отправленных пользователем», таких как запуск / остановка / перезапуск / обновление. То, чем вы их заменяете, зависит от вашего варианта использования: вы можете использовать переменную обмена сообщениями или, если ваш основной процесс находится в цикле сервера, вы можете "выбрать" в канале в верхней части цикла, чтобы увидеть если ребенок отправил сообщение об обновлении. Я, наверное, скучаю по многим другим.

0 голосов
/ 08 июня 2009

Как уже говорили другие, это может быть больше проблем, чем стоит.

Однако, если вы настаиваете.

Вероятно, проще всего открыть две трубы, используя режимы popen и rw, перед тем как создать поток. Выберите один для main -> thread и другой для main <- thread и просто продолжайте. </p>

Или вы можете открыть всего четыре файловых дескриптора после создания, как если бы это были два разных процесса

...