У меня есть проект, который, как я думал, будет относительно легким, но оказывается более больным, чем я надеялся. Во-первых, большая часть кода, с которым я взаимодействую, - это устаревший код, который я не контролирую, поэтому я не могу делать большие изменения парадигмы.Crossplatform двунаправленный IPC
Вот упрощенное объяснение того, что мне нужно сделать. Скажем, у меня есть большое количество простых программ, которые читаются из stdin и записываются в stdout. (Это я не могу трогать). В принципе, вход в stdin - это команда типа «Установить температуру до 100» или что-то в этом роде. И выход - это событие «Температура установлена на 100» или «Температура упала ниже заданного значения».
Что бы я хотел сделать, это написать приложение, которое может запускать кучу этих простых программ, следить за событиями и затем при необходимости отправлять команды им. Мой первоначальный план состоял в том, что-то вроде popen, но мне нужно использовать двунаправленный popen, чтобы получить как чтение, так и запись. Я взломал что-то вместе, что я называю popen2, где я передаю ему команду для запуска, и два FILE *, которые заполняются потоком чтения и записи. Тогда все, что мне нужно сделать, это написать простой цикл, который читает из каждого из stdouts из каждого из процессов, выполняет ли логику, в которой он нуждается, а затем записывает команды обратно в соответствующий процесс.
Вот некоторые псевдокод
FILE *p1read, *p1write;
FILE *p2read, *p2write;
FILE *p3read, *p3write;
//start each command, attach to stdin and stdout
popen2("process1",&p1read,&p1write);
popen2("process2",&p2read,&p2write);
popen2("process3",&p3read,&p3write);
while (1)
{
//read status from each process
char status1[1024];
char status2[1024];
char status3[1024];
fread(status1,1024,p1read);
fread(status2,1024,p2read);
fread(status3,1024,p3read);
char command1[1024];
char command2[1024];
char command3[1024];
//do some logic here
//write command back to each process
fwrite(command1,p1write);
fwrite(command2,p2write);
fwrite(command3,p3write);
}
Настоящая программа является более сложной, когда он заглядывает в потоке, чтобы увидеть, если что-то ждет, если нет, то он пропустит этот процесс, также, если это не нужно отправьте команду на определенный процесс, которого нет. Но этот код дает основную идею.
Теперь это отлично работает на моей коробке UNIX и даже довольно хорошо на коробке Windows XP с cygwin. Однако теперь мне нужно заставить его работать на Win32 изначально.
Жесткая часть заключается в том, что мой popen2 использует fork() и execl() для запуска процесса и назначения потоков для stdin и stdout дочерних процессов. Есть ли чистый способ сделать это в окнах? В принципе, я хотел бы создать popen2, который работает в окнах так же, как моя версия unix. Таким образом, единственный конкретный код для Windows будет в этой функции, и я мог бы уйти со всем остальным, работающим одинаково.
Любые идеи?
Спасибо!
Там нет вилки() механизма, доступного в WIN32, хотя продукт Interix, видимо, не поддерживает его. – 2009-05-28 14:23:48
Так же и Cygwin. Я знаю, что есть проблемы и трудности - следовательно, ласковые слова, которые достигают эффекта вилки и exec. – 2009-05-28 15:33:28