2016-03-26 5 views
0

Я хочу сделать модель полностью подключенной топологии сетки. У меня есть родитель и дети, которые общаются друг с другом с помощью труб. Поэтому каждый процесс должен читать данные из нескольких труб. И я не знаю, как это сделать.Чтение данных из нескольких труб

Каждый процесс имеет «локальный идентификатор» в качестве приращения (0 - родительский, 1,2,3 и т. Д.).

Я создал 2d массив труб. А первый массив - направления, вторые массивы - источники:

struct pipes_t 
{ 
    int rdwr[2]; 
}; 

struct dataIO_t 
{ 
    int processes; // number of processes 
    int8_t lid; // prosecc local id (0,1,2 etc) 
    struct pipes_t pipes[MAX_LOCAL_ID+1][MAX_LOCAL_ID+1]; 
}; 

Функция для отправки многоадресного сообщения:

int send(struct dataIO_t* data) { 
    for(int i = 0; i < data->processes; i++) 
     if(write(data->pipes[i][data->lid].rdwr[1], "Hello world\n", 12) != 1) 
      return 1; 
    return 0; 
} 

Как читать данные из многих труб из любого процесса без резьбы? Я пытался использовать функцию dup2 для подключения всех труб в одном, но это была плохая идея:

int receive(struct dataIO_t* data) { 
    int fd[2]; 
    pipe(fd); 

    const int BSIZE = 100; 
    ssize_t nbytes; 
    char buf[BSIZE]; 

    for(int i = 0; i < data->processes; i++) 
     if(i != data->lid) 
      if (dup2(data->pipes[data->lid][i].rdwr[0], fd[0]) == -1) 
       return 1; 

    nbytes = read(fd[0], buf, BSIZE); 
    printf("Msg (%d): %s\n", data->lid, buf); 

    return 0; 
} 

Запреты: в этом упражнении я не могу использовать poll, select и те же функции.

+0

Функция вы ищете 'poll'; он ждет нескольких дескрипторов файлов и возвращает, какие из них готовы для чтения или записи. Существует также 'select', который является старым, и' epoll', что немного сложнее. –

+0

@ColonelThirtyTwo Я обновил вопрос, я не могу использовать эти функции –

+0

Ну, если вы не можете использовать разумные параметры (['select()'] (http://pubs.opengroup.org/onlinepubs/9699919799/ functions/select.html) и ['poll()'] (http://pubs.opengroup.org/onlinepubs/9699919799/functions/poll.html) и нестандартных родственников), тогда вам нужно будет сделать дескрипторы read file неблокируются (['fcntl()'] (http://pubs.opengroup.org/onlinepubs/9699919799/functions/fcntl.html), 'F_GETFL',' F_SETFL' и 'O_NONBLOCK') и вам придется перебирать каждый дескриптор файла, чтобы узнать, есть ли какие-либо данные для чтения. –

ответ

3

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

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

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

В псевдокоде:

for each fd in fds 
    mode = fcntl(fd, F_GETFL); 
    fcntl(fd, F_SETFL, mode | O_NONBLOCK) 

forever 
    for each fd in fds 
     if read(fd) 
      process data 
    sleep a little to avoid 100% CPU usage 
+0

Выполняет ли 'setsockopt()' работу над дескрипторами каналов, а не дескрипторами сокетов? –

+0

@JonathanLeffler: Хорошо, я обновил свой псевдокод, чтобы использовать 'fcntl()', который определенно работает (в той мере, в какой псевдокод может определенно работать!). –

+0

Вы должны использовать 'select' или' poll' вместо оживленного ожидания. – jch

Смежные вопросы