2016-04-12 26 views
0

İki alt işlem oluşturmaya ve bunları pipetlemeye çalışıyorum, ancak ikinci çocuk ilk çocuk tarafından üretilen çıktıyı sıralamıyor. ls yapar. Neyi yanlış yapıyorum?İki alt işlem için bir tane, biri diğeri için sıralama, ancak sıralama çalışmıyor

#include <stdio.h> 
#include <stdlib.h> 
#include <unistd.h> 

int main(int argc, char *argv[]) { 
    int pipefd[2]; 
    pid_t ls_pid, wc_pid; 

    pipe(pipefd); 

    if ((ls_pid = fork()) == 0) { 

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

    execl("/bin/ls", "ls", 0); 
    perror("exec ls failed"); 
    exit(EXIT_FAILURE); 
    } 


    if ((wc_pid = fork()) == 0) { 

    dup2(pipefd[0], STDIN_FILENO); 

    close(pipefd[1]); 
    execl("/usr/bin/sort", "sort", NULL); 
    perror("exec wc failed"); 
    exit(EXIT_FAILURE); 
    } 


    return EXIT_SUCCESS; 
} 
+1

"ama ikinci çocuk çıktısını sıralamak değildir". Kesin davranış nedir? – kaylum

+0

ikinci çocuk sadece ls her öğeyi yeni bir satır – freakyfrog

+0

Tamam, ama çıktı sıralanır? Kodunu denedim ve benim için çalıştı. – kaylum

cevap

0

Sen ikinci birinde yaptığımız gibi firt execl üçüncü parametre olarak NULL geçmek zorunda. Ne olur execl düzgün yürütür (bu yüzden bir hata alamıyorsunuz), ancak geçersiz bir komut verdiğinizde ls komutu çalışmaz. Btw , sen fork()

+0

Ama ls çalışıyor, teknik olarak çalışmıyor ne tür. Sıralama, ls 'in her öğesini stdout'ta yeni bir satıra yazdırır. Ben denedim ve hala aynı – freakyfrog

+0

Ben senin sıralama hiç bir şey yapmıyor düşünüyorum, ebeveyn sürecinin bitmeden önce sistem ("pstree") 'yi eklemeyi deneyin ve bir sıralama işlemi bitmemiş olup olmadığını görün. Ayrıca kodunuzu çalıştırıp terminalden 'pstree' komutunu da çalıştırıyorsunuz. – Nevado

1

sıralama çalışması gerekir gibi, tüm OS isteklerinde hata kontrolünü yapmalıdır, ancak kodda 2 uyarılar vardır, önce fd başvurular tutan tüm süreçlerde emin yakın fd yapmak aksi halde fd kapanmaz ve bu yüzden sıralama işlemi bittiğinde orada askıda kalıyor, çünkü EEF'yi stdin'den almıyor, ve üst süreçteki pipefd kapalı olmadığından. Diğeri ise çocukların çıkıp çıkış durumlarını kontrol etmelerini bekler. Yorumların tamamını birleştiren

close(pipefd[0]); 
close(pipefd[1]); 

int status; 
int pid = waitpid(ls_pid, &status, 0); 
pid = waitpid(wc_pid, &status, 0); 
+0

Ebeveynler çıkış yaptıklarından, arka planda çocukları etkili bir şekilde çalıştırdıklarından, ebeveynin boruları açıkça kapatmaması önemli değil; Çıktığı zaman sistem tarafından kapatılırlar. Ancak, ebeveyn asılmak ve çocukların tamamlanmasını beklemekse, bu durumda borunun her iki ucunu da kapatması çok önemlidir. –

+0

Evet, bu standart çıktıda çıktı veren bir işlem olduğu için, bir arka planda arka planda çalışan bir tane değil, ebeveynin çıktığı ve konsolda bir şeyler çıktığında garip bir şey olduğunu düşünüyorum, işte bu yüzden Ebeveynleri bitirmeden önce çocukların çıkmasını bekleyin. – fluter

0

ve test edilmiş: Ana fonksiyonun gönderme için aşağıdaki ekleyin

#include <stdio.h> 
#include <stdlib.h> 
#include <sys/types.h> 
#include <sys/wait.h> 
#include <unistd.h> 

int main(int argc, char *argv[]) { 
    int pipefd[2]; 
    pid_t ls_pid, wc_pid; 
    int status; 

    pipe(pipefd); 

    if ((ls_pid = fork()) == 0) { 

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

    execlp("ls", "ls", NULL); 
    perror("exec ls failed"); 
    exit(EXIT_FAILURE); 
    } 


    if ((wc_pid = fork()) == 0) { 

    dup2(pipefd[0], STDIN_FILENO); 
    close(pipefd[0]); 
    close(pipefd[1]); 
    execlp("sort", "sort", NULL); 
    perror("exec sort failed"); 
    exit(EXIT_FAILURE); 
    } 
    close (pipefd[0]); 
    close (pipefd[1]); 

    /* wait for two children to finish */ 
    wait(&status); 
    wait(&status); 


    return EXIT_SUCCESS; 
}