Сегодня я столкнулся с небольшой проблемой на C, где я не могу понять, почему мои процессы не «выстраиваются» в том, как они используют канал.Передача данных через каналы в C между несколькими дочерними процессами (среда UNIX)
У меня есть 2 дочерних процесса, разветвленных из родительского процесса, которые записывают некоторые данные, и они должны записывать эти данные в трубу. Затем труба периодически считывается родительским процессом и «освобождается» от данных в трубе и печатается в терминальной линии. Затем все это повторяется.
//Creates Three Processes A,B,C which communicate data through a pipe.
int main(void) {
int fd[2], nbytes;
pid_t childpidB, childpidC;
char readbuffer[100];
readbuffer[0] = '\0';
pipe(fd);
if((childpidB = fork()) < 0)
{
perror("fork B error.");
exit(1);
}
if(childpidB == 0)
{
close(fd[0]);
char AAA[3] = {'A','A','A'};
int j = 0;
int k = 1;
while (j < 500) {
if(j%100==0 && j!=0) {
usleep(100);
}
char numbers[6];
numbers[0] = '\0';
sprintf(numbers,"%03dAAA",k);
k++;
j++;
write(fd[1], numbers, (strlen(numbers)+1));
}
close(fd[1]);
exit(0);
}
if((childpidC = fork()) < 0)
{
perror("fork C error.");
exit(1);
}
if(childpidC == 0)
{
close(fd[0]);
int i = 0;
char c = 'A';
int numberafter = 0;
while (i < 260) {
if(i%60==0 && i!=0) {
usleep(300);
}
char dump[3];
dump[0] = '\0';
if(c=='[') { c='A'; numberafter++; }
sprintf(dump,"%cx%d\n",c,numberafter);
c++;
write(fd[1], dump, (strlen(dump)+1));
i++;
}
close(fd[1]);
exit(0);
}
//Process A
if(childpidC > 0 && childpidB > 0) {
int x = 0;
close(fd[1]);
while (nbytes = read(fd[0], readbuffer, sizeof(readbuffer)) > 0) {
if(x%50==0 && x!=0) {
usleep(200);
}
printf("%s\n", readbuffer);
x++;
}
close(fd[0]);
exit(0);
}
}
Моя проблема заключается в том, что родительский процесс не всегда считывает 100 символов из трубы, и я не уверен, как это может произойти. Он только считывает небольшой фрагмент данных из каждой трубы, прежде чем ломаться. Предполагается, что каждый раз считывается 100 символов из трубы. Вот пример вывода:
001AAA
Ax0
Gx0
Ox0
...(keeps going for a while)...
Я задаюсь вопросом, почему/как это только чтение небольшое количество данных из трубы каждый раз. Данные, которые он читает, действительно выглядят правильно, но это просто не чтение 100 символов в строке (как я думал, это логически должно быть, в моем коде). Затем он как-то ничего не читает из трубы и записывает только пустую строку (потому что он не читает никаких символов, но все равно печатает пустую строку). Это должно означать, что дочерние процессы только записывают несколько символов в канал на каждой итерации, но я не понимаю, как это может быть. Выход также различается при каждом запуске программы.
Похоже, что ребенок обрабатывает и родители не синхронизированы, но я думал, что для этого потребуется закрыть соответствующий интервал fd [0] или fd [1].
EDIT: Я обновил код, чтобы приблизиться к тому, что я хочу (или, возможно, именно то, что хочу, нужно больше тестировать). Это связано с пропуском слишком много символов NULL.
int main(void) {
int fd[2], nbytes;
pid_t childpidB, childpidC;
char readbuffer[100];
readbuffer[0] = '\0';
pipe(fd);
if((childpidB = fork()) < 0)
{
perror("fork A error.");
exit(1);
}
if(childpidB == 0)
{
close(fd[0]);
char AAA[3] = {'A','A','A'};
int j = 0;
int k = 1;
while (j < 500) {
if(j%100==0 && j!=0) {
usleep(100);
}
char numbers[6];
numbers[0] = '\0';
sprintf(numbers,"%03dAAA",k);
k++;
j++;
write(fd[1], numbers, (strlen(numbers)));
}
close(fd[1]);
exit(0);
}
if((childpidC = fork()) < 0)
{
perror("fork B error.");
exit(1);
}
if(childpidC == 0)
{
close(fd[0]);
int i = 0;
char c = 'A';
int numberafter = 0;
while (i < 260) {
if(i%60==0 && i!=0) {
usleep(300);
}
char dump[3];
dump[0] = '\0';
if(c=='[') { c='A'; numberafter++; }
sprintf(dump,"%cx%d",c,numberafter);
c++;
write(fd[1], dump, (strlen(dump)));
i++;
}
close(fd[1]);
exit(0);
}
//Process A
int x = 0;
close(fd[1]);
if(childpidB > 0 && childpidC > 0) {
while ((nbytes = read(fd[0], readbuffer, sizeof(readbuffer))) > 0) {
if(x%50==0 && x!=0) {
usleep(200);
}
printf("%s\n", readbuffer);
x++;
}
}
close(fd[0]);
exit(0);
}
пытаются напечатать количество записанных байтов и читать ... –