2010-05-02 5 views
0

Я вижу, что легко открыть трубку между двумя процессами, используя вилку, но как мы можем передавать открытую трубу в потоки. Предположим, нам нужно пройти из ПРОГРАММЕ А в ПРОГРАММЕ B «может более чем одной нити», ПРОГРАММА B отправить свой вывод ПРОГРАММА СПодача нитей другой MultiThreading

EDIT: возвращусь после изменения кода, чтобы стать более легким для чтение.

#include <stdio.h> 
#include <stdlib.h> 
#include <pthread.h> 
#include <fcntl.h> 

void *thread1(void *arg) { 

    int status, fd[2]; 
    pid_t pid; 

    pipe(fd); 
    pid = fork(); 

    if (pid == 0) { 
     int fd2 = *((int *) (arg)); 
     dup2(STDIN_FILENO, fd2); 

     close(fd[0]); 
     dup2(fd[1], STDOUT_FILENO); 
     close(fd[1]); 

     execvp("PROGRAM B", NULL); 
     exit(1); 
    } else { 
     close(fd[1]); 
     dup2(fd[0], STDIN_FILENO); 
     close(fd[0]); 

     execl("PROGRAM C", NULL); 
     wait(&status); 

     return NULL; 
    } 
} 

int main(void) { 


    FILE *fpipe; 
    char *command = "PROGRAM A"; 
    char buffer[1024]; 

    if (!(fpipe = (FILE*) popen(command, "r"))) { 
     perror("Problems with pipe"); 
     exit(1); 
    } 

    char* outfile = "out.dat"; 
    //FILE* f = fopen (outfile, "wb"); 
    //int fd = fileno(f); 

    int fd[2]; 
    fd[0] = open(outfile, O_WRONLY); 

    pthread_t thid; 
    if (pthread_create(&thid, NULL, thread1, fd) != 0) { 
     perror("pthread_create() error"); 
     exit(1); 
    } 

    int len; 
    while (read(fpipe, buffer, sizeof (buffer)) != 0) { 
     len = strlen(buffer); 
     write(fd[0], buffer, len); 
    } 

    pclose(fpipe); 

    return (0); 
} 
+3

Обычно вы не используете каналы между потоками, так как они имеют общее адресное пространство. Усилие сериализации данных через байтовый насос обычно не стоит. –

+1

@Marcelo: Это действительно зависит от того, какое точное сообщение вы отправляете. Один из подходов может заключаться в том, чтобы создать сообщение в виде структуры в памяти и отправить его адрес (плюс ответственность за его порядок) по каналу в виде простого 4/8 байтового сообщения. (Есть другие случаи, когда трубы между потоками жизненно важны, например, когда у вас есть некоторые потоки, используя 'select()' ...) –

+0

+1 Дональд. Да, ваши баллы действительны, поэтому мой квалифицированный язык. Тем не менее, помимо проблемы «select», я обычно предпочитаю очереди POSIX из-за их основанной на пакетах (в отличие от байт-ориентированной) семантики. –

ответ

0

Для обмена сообщениями между процессами очереди POSIX, скорее всего, удовлетворят ваши потребности лучше, чем трубы. Выезд man mq_overview (или online).

+0

Я не думаю о связи между моим Q и вашим воспроизведением. можете ли вы привести пример, чтобы показать, что mq_overview и execvp работают вместе. спасибо – alaamh