Как каналы Unix могут использоваться между основным процессом и потоком?

Хотя ответ Конамимана является точным, я хотел бы добавить, что в конкретном случае открытых сеттеров по сравнению с прямым представлением открытых полей, о которых вы спрашиваете, существует еще одно очень важное различие, которое следует иметь в виду, помимо сокрытия информации и , отделяющего реализацию от общедоступной поверхности или API класса; Проверка .

В сценарии открытого поля нет способа проверить значение поля при его изменении. В случае с общедоступным установщиком (будь то свойство Foo {get; set;} или SetFoo(Foo value)) у вас есть возможность добавить проверочный код и запустить необходимые побочные эффекты, и таким образом убедиться, что ваш класс всегда находится в допустимом или предсказуемом состоянии .

7
задан GEOCHET 9 June 2009 в 18:31
поделиться

5 ответов

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

Шаг первый вызов pipe для получения канала:

  #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));
     }
 }
13
ответ дан 6 December 2019 в 10:52
поделиться

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

4
ответ дан 6 December 2019 в 10:52
поделиться

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

1
ответ дан 6 December 2019 в 10:52
поделиться

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

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

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

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

0
ответ дан 6 December 2019 в 10:52
поделиться

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

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

kill(getppid(), SIGUSR1);

, чтобы отправить сигнал родителю. У других есть приведенный выше код для создания файловых дескрипторов и их перехвата на родительской стороне.

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

0
ответ дан 6 December 2019 в 10:52
поделиться
Другие вопросы по тегам:

Похожие вопросы: