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;
}
Другие вопросы по тегам