نسخة سلسلة باستخدام الأنابيب
سؤال
لقد كتبت البرمجية التالية إلى نسخ سلسلة "مرحبا العالم" إلى آخر شار المصفوفة باستخدام شوكة و أنابيب بدلا من استخدام المكتبة القياسية وظائف أو معيار i/o تيارات.البرنامج هو تجميع بنجاح ولكن أنا لا تحصل على أي الإخراج.حتى printf الإخراج لا يتم عرضها.
# include <string.h>
# include <unistd.h>
# include <stdio.h>
char string[] = "hello world";
int main()
{
int count, i;
int toPar[2], toChild[2];
char buf[256];
pipe(toPar);
pipe(toChild);
if (fork() == 0)
{
printf("\n--- child process ---");
close(0);
dup(toChild[0]);
close(1);
dup(toPar[1]);
close(toPar[1]);
close(toChild[0]);
close(toPar[0]);
close(toChild[1]);
for (;;)
{
if ((count = read(0, buf, sizeof(buf))) == 0)
break;
printf("\nChild buf: %s", buf);
write(1, buf, count);
}
}
printf("\n--- parent process ---");
close(1);
dup(toChild[1]);
close(0);
dup(toPar[0]);
close(toPar[1]);
close(toChild[0]);
close(toPar[0]);
close(toChild[1]);
for (i = 0; i < 15; i++)
{
write(1, string, strlen(string));
printf("\nParent buf: %s", buf);
read(0, buf, sizeof(buf));
}
return 0;
}
المحلول
الخاص بك printf
s هي الكتابة stdout
ولكن في كلا من الأم والطفل ، كنت قد إعادة توجيه ملف واصف 1 إلى الأنابيب ، لذلك هذا هو المكان الذي printf
الناتج سوف تذهب.
بدلا من printf(...)
, استخدام fprintf(stderr, ...)
- ثم عليك أن تكون قادرا على رؤية الإخراج ، منذ stderr
لا يزال لافتا إلى محطة الخاص بك.
لاحظ أن لديك زوجين من الخلل:
- الطفل يجب استدعاء
_exit(0)
عندما يتم ذلك, وإلا فإنه سوف تسقط في الأصل رمز; - على
write
يجب استخدامstrlen(string) + 1
, بحيث يكتب nul منهي.
نصائح أخرى
حاول إضافة " n" ، مثل printf("\nParent buf: %s\n", buf);
أعتقد أن هذه الأنابيب تقوم بحظر IO ، لذلك لن تعود القراءة ببساطة إلا إذا تم إغلاق الأنبوب من قبل العملية الأخرى. هذا ، و printf القيام بموقد IO ، يمنعك من الحصول على أي إخراج.