Отправить сигнал приостановленному родительскому процессу и гарантировать, что он прибудет ПОСЛЕ приостановки родительского процесса

Это просто сортирует ввод в обратном порядке, так что «foobar» идет перед «foo», а затем не печатает текущую строку (foo )если это подстрока предыдущей (foobar )начиная с первого символа каждого.

$ sort -r file | awk 'index(prev FS,$0 FS) != 1; {prev=$0}'
h   ii  j
dddd    eeee    fe
dddd    eeee    f   g
aaaa    bbbb    xx
aaaa    bbbb    x
aaaa    bbbb    cc
aaaa    bbbb    c   dd

Если для вас важен порядок вывода, есть способы решить эту проблему, например.:

$ cat -n file | sort -k2r |
    awk '{orig=$0; $1=""} index(prev FS,$0 FS) != 1{print orig} {prev=$0}' |
    sort -n | cut -f2-
aaaa    bbbb    c   dd
aaaa    bbbb    cc
aaaa    bbbb    x
aaaa    bbbb    xx
dddd    eeee    f   g
dddd    eeee    fe
h   ii  j
-1
13.11.2020, 02:48
1 ответ

Вы правы, ваша программа подвержена гонкам.

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

Очень приблизительно:

#define CHILDREN 5
int main()
{
    int pid;
    int pipes[CHILDREN][2];
    
    for(int i = 0; i < CHILDREN; i++)
    {
        if (pipe(pipes[i]) == -1) {
           // Error
        ]
        
        pid = fork();
        if(pid == -1) {
          // Error
        } else if (pid == 0) {
            // Child   
            close(pipes[i][0]);
            mapp(i, pipes[i][1]);
        } else {
            // Parent
            close(pipes[i][1]);
        }
    }

    for(int i = 0; i < CHILDREN; i++)
    {
        /*Parent reads from the pipe number i => SUCCESS*/ 
        read(pipes[i][0],...); // Will block until children writes
    }
    
    
}

void mapp(int i, int fd)
{
    /*Children writes to its pipe */
    write(fd, "hello Dad!\n", 11);
}

Родительский объект будет блокироваться до тех пор, пока не сможет прочитать из канала, поэтому он полностью эффективен. Если вы хотите заблокировать, пока он не сможет читать из любого канала, вы можете сделать это, используя select, epoll и т. д.

Записи в каналы являются атомарными при условии, что их размер меньше PIPE _BUF (в Linux, это 4096 байт ). В последних версиях Linux вы можете использовать O _DIRECT и также иметь «пакетный» режим. Хотя так как у вас была бы труба на ребенка, то это кажется излишним.

0
18.03.2021, 22:49

Теги

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