C под Ubuntu - не ожидаемый результат, пытаясь решить "Колесо игры"
Колесо. Основной процесс (A) создаст подпроцесс (B), который создаст другой подпроцесс (C). Затем основной процесс (A) отправит сгенерированное случайное число (от 1000 до 2000) на процесс B. Процесс B вычтет 10 единиц и отправит число на процесс C. C вычтет 20 единиц и отправит число A. Процесс A вычтет 30 единиц и снова отправит число B. И так до тех пор, пока значения не станут меньше нуля. В этот момент игра остановится. Победителем считается процесс, который установил отрицательное число.
Связь между всеми процессами осуществляется через каналы каналов.
Мое решение было:
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <time.h>
#include <sys/types.h>
#include <sys/wait.h>
int pass(char* id, int in, int out, int x)
{
int n;
read(in, &n, sizeof(int));
printf("%s %d\n", id, n);
n=n-x;
printf("x= %d\n", x);
write(out, &n, sizeof(int));
return n;
}
void closeall(int* a, int* b, int* c)
{
close(a[0]);
close(a[1]);
close(b[0]);
close(b[1]);
close(c[0]);
close(c[1]);
}
int main()
{
int a2b[2], b2c[2], c2a[2], n, x;
pipe(a2b);
pipe(b2c);
pipe(c2a);
srand(time(NULL));
n=rand() % 1001 + 1000;
x=0;
write(c2a[1], &n, sizeof(int));
if (fork() == 0){
while (pass("grandfather ", c2a[0], a2b[1], x) > 0){
x=x+10;}
exit(0);
}
if (fork() == 0){
while (pass("father ", a2b[0], b2c[1], x) > 0){
x=x+10;}
exit(0);
}
if (fork() == 0){
while (pass("child ", b2c[0], c2a[1], x) > 0){
x=x+10;}
exit(0);
}
closeall(a2b, b2c,c2a);
wait(0);
wait(0);
wait(0);
return 0;
}
После запуска программы результат был
grandfather 1420
x= 0
father 1420
x= 0
child 1420
x= 0
grandfather 1420
x= 10
father 1410
x= 10
child 1400
x= 10
grandfather 1390
x= 20
father 1370
x= 20
child 1350
x= 20
grandfather 1330
x= 30
father 1300
x= 30
child 1270
x= 30
grandfather 1240
x= 40
father 1200
x= 40
child 1160
x= 40
grandfather 1120
x= 50
father 1070
x= 50
child 1020
x= 50
grandfather 970
x= 60
father 910
x= 60
child 850
x= 60
grandfather 790
x= 70
father 720
x= 70
child 650
x= 70
grandfather 580
x= 80
father 500
x= 80
child 420
x= 80
grandfather 340
x= 90
father 250
x= 90
child 160
x= 90
grandfather 70
x= 100
father -30
x= 100
child -130
x= 100
Может ли кто-нибудь помочь мне улучшить исходный код, чтобы получить правильный результат? Как было показано ранее, вычтенное значение x одинаково трижды и не останавливается после первого отрицательного числа.
2 ответа
В вашей программе многопоточность вообще не имеет никакого смысла, так как каждый поток должен либо ждать, пока он не получит следующее значение, либо вычислить в данный момент, потому что каждый поток нуждается в результате предыдущего. Это будет означать, что всегда есть два ожидающих потока и один в настоящий момент запущенный.
Это также проблема вашей программы. Потоки работают асинхронно и не ждут, пока предыдущий завершит свой расчет.
Предоставленное решение неверно, потому что процессы A,B,C являются братьями. Решение, в котором A является прародителем, B является родительским, а C является дочерним по отношению к B, следующее:
Это решение:
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <time.h>
#include <sys/types.h>
#include <sys/wait.h>
int n;
int a2b[2], b2c[2], c2a[2], x;
void closeall(int* a, int* b, int* c)
{
close(a[0]);
close(a[1]);
close(b[0]);
close(b[1]);
close(c[0]);
close(c[1]);
}
int passData(char* id, int in, int out, int x)
{
read(in, &n, sizeof(int));
printf("%s %d \n", id, n); // afisarea in plus pentru verificare
if( n < 0 ) {
printf ("WINNER is: %s %d\n ", id, n);
return n;
}
n=n-x;
printf("x= %d\n", x); // afisarea in plus pentru verificare
write(out, &n, sizeof(int));
return n;
}
int main()
{
pipe(a2b);
pipe(b2c);
pipe(c2a);
srand(time(NULL));
n=rand() % 1001 + 1000;
x=0;
write(c2a[1], &n, sizeof(int));
while (passData("A", c2a[0], a2b[1], x) > 0){
x=10;
}
if (fork() == 0){
if (fork() == 0){
while (passData("C", b2c[0], c2a[1], x) > 0){
x=30;
}
while (passData("B", a2b[0], b2c[1], x) > 0){
x=20;
}
wait(0);
exit(0);
}
closeall(a2b, b2c,c2a);
wait(0);
wait(0);
wait(0);
return 0;
}