我想不出有什麼辦法可以在c中實現流水線操作。這就是爲什麼我決定寫在這裏。我必須說,我知道pipe/fork/mkfifo是如何工作的。我已經看到了很多實施2-3條管道的例子。這很容易。我的問題開始了,當我需要實現shell時,管道數量還未知。在c中實現流水線。什麼是最好的方式來做到這一點? (自己的linux外殼)
我現在得到了什麼: eg。
ls -al | tr a-z A-Z | tr A-Z a-z | tr a-z A-Z
我的變換,例如行成這樣的事情:
array[0] = {"ls", "-al", NULL"}
array[1] = {"tr", "a-z", "A-Z", NULL"}
array[2] = {"tr", "A-Z", "a-z", NULL"}
array[3] = {"tr", "a-z", "A-Z", NULL"}
所以我可以在以後使用
execvp(array[0],array)
。
現在,我相信一切都好。問題開始,當我試圖將這些函數的輸入/輸出重定向到彼此。
以下是我正在做的是:
mkfifo("queue", 0777);
for (i = 0; i<= pipelines_count; i++) // eg. if there's 3 pipelines, there's 4 functions to execvp
{
int b = fork();
if (b == 0) // child
{
int c = fork();
if (c == 0)
// baby (younger than child)
// I use c process, to unblock desc_read and desc_writ for b process only
// nothing executes in here
{
if (i == 0) // 1st pipeline
{
int desc_read = open("queue", O_RDONLY);
// dup2 here, so after closing there's still something that can read from
// from desc_read
dup2(desc_read, 0);
close(desc_read);
}
if (i == pipelines_count) // last pipeline
{
int desc_write = open("queue", O_WRONLY);
dup2(desc_write, 0);
close(desc_write);
}
if (i > 0 && i < pipelines_count) // pipeline somewhere inside
{
int desc_read = open("queue", O_RDONLY);
int desc_write = open("queue", O_WRONLY);
dup2(desc_write, 1);
dup2(desc_read, 0);
close(desc_write);
close(desc_read);
}
exit(0); // closing every connection between process c and pipeline
}
else
// b process here
// in b process, i execvp commands
{
if (i == 0) // 1st pipeline (changing stdout only)
{
int desc_write = open("queue", O_WRONLY);
dup2(desc_write, 1); // changing stdout -> pdesc[1]
close(desc_write);
}
if (i == pipelines_count) // last pipeline (changing stdin only)
{
int desc_read = open("queue", O_RDONLY);
dup2(desc_read, 0); // changing stdin -> pdesc[0]
close(desc_read);
}
if (i > 0 && i < pipelines_count) // pipeline somewhere inside
{
int desc_write = open("queue", O_WRONLY);
dup2(desc_write, 1); // changing stdout -> pdesc[1]
int desc_read = open("queue", O_RDONLY);
dup2(desc_read, 0); // changing stdin -> pdesc[0]
close(desc_write);
close(desc_read);
}
wait(NULL); // it wait's until, process c is death
execvp(array[0],array);
}
}
else // parent (waits for 1 sub command to be finished)
{
wait(NULL);
}
}
感謝。
現在每個人都在寫自己的外殼嗎?本週有關「我自己的外殼」的第三個問題。 – 2012-11-11 14:32:28
@ H2CO3這可能與操作系統類別分配有關。至少,在我的第一個操作系統類中,我必須編寫一個shell。 – mah