Массив каналов: загрузит ли родительский процесс массив достаточно быстро?

#c #linux #pipe

#c #linux #канал

Вопрос:

     for (int i = 0; i < number_processes; i  ){

        while (read(fps[i][0], amp;each_record_read, sizeof(struct rec)) > 0){
            if (records_container[i] == NULL){
                records_container[i] = amp;each_record_read;
            }
        } // I want to do something to records_container here.
    }
  

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

Я определил массив с именем records_container, который содержит каждый тип данных, которые я собираюсь прочитать из канала, и я хочу что-то сделать с этим массивом после цикла while.

Мой вопрос заключается в следующем: когда родительский процесс загружает данные в records_container этот массив, достаточно ли высока скорость загрузки родительского процесса, чтобы, когда я хочу что-то сделать с records_container, я всегда мог убедиться, что все данные уже загружены идеально?

Давайте предположим, что records_container в этом случае равен {0, 0, 0, 0} (я знаю, что хочу загрузить struct rec, но на самом деле это не имеет значения), идеальная ситуация, в которой я хочу, чтобы это произошло, заключается в том, что я хочу иметь дело с загруженным массивом, который равен {1, 2, 3, 4} в этом случае, будет ли родительский процесс достаточно быстро считывать каждое число (которое в данном случае равно 1, 2, 3, 4 из каждого канала), так что я не буду иметь дело с чем-то вроде {1, 2, 0, 0}, или {1, 0, 0, 0} … что-то в этом роде?

Комментарии:

1. Ваш цикл не будет обрабатывать второй канал, пока не получит EOF из первого канала. И тогда он не будет обрабатывать третий канал, пока не получит EOF из второго канала. И так далее.

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

3. Да, я тоже так чувствую, но на самом деле не уверен, спасибо, что указали на это. Есть ли какой-либо способ, который может позволить мне пропустить чтение из первого канала и сразу перейти к следующему каналу для чтения?

4. Операции чтения и записи в канале являются атомарными, см. unix.stackexchange.com/questions/346755 /…

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

Ответ №1:

Это не работает.

 while (read(fps[i][0], amp;each_record_read, sizeof(struct rec)) > 0)
  

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

 ssize_t read_block(int source, void *buffer, ssize_t len)
{
    char *work = buffer;
    while (len) {
        ssize_t delta = read(source, work, len);
        if (delta < 0) return -1; /* ERROR */
        if (delta == 0) return 0; /* EOF */
        work  = delta;
        len -= delta;
    }
}

/* ... */

    while (read_block(fps[i][0], amp;each_record_read, sizeof(struct rec)) > 0){
  

Теперь это работает.

Комментарии:

1. Я в некотором роде новичок в этом деле, может ли этот код реализовать функциональность «перейти к чтению канала»?

2. @DigitalSoul: Что вообще означает переход по каналу чтения? Похоже, это не входит в вопрос.