Проблема при попытке использовать несколько процессов для создания сита Eratosthenes в C (Unix) - PullRequest
0 голосов
/ 23 апреля 2020

Я пытаюсь написать сценарий оболочки (bash) для построения решета Эратосфена, используя несколько процессов.

Моя проблема в том, что моя функция застряла на бесконечном l oop, и я не знаю почему. Я чувствую, что что-то происходит с тем, как я имею дело с рекурсией и копиями, которые процесс делает из всех переменных, существующих на текущем этапе, но я не знаю, что именно.

То, как я думал реализовать это следующим образом, объясненным на естественном языке.

Прежде всего я рассмотрел массив bool и пометил все четные числа как составные (за исключением, конечно, 2), чтобы повысить эффективность. Затем я разбираюсь с остальными числами, такими как:

1) Создайте процесс.

2) Если больше нет составных чисел отмечен в массиве STOP (я проверяю это в родительском процессе)

3) В противном случае проверьте, является ли текущее число простым; если так, то пометьте все кратные текущего числа как не простые. (Я делаю это в дочернем процессе)

Примечание: в моей реализации, если sieve[i] == false then i простое число; i является составным, в противном случае.

4) Повтор

Хорошо ли мои логики c хорошо?

Примечание: Я точно знаю, что неизвестно, когда поток управления передается ребенку. Тем не менее, я заметил, что на моей машине это родитель, к которому обращаются первыми при каждом рекурсивном вызове, который я делаю (тот же случай для итераций в for-l oop)

Это то, что я пытался до сих пор:

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdbool.h>

#define Nmax 105

void afis(bool *arr, int n)
{
    for(int i = 0; i <= n; i++)
        if(arr[i] == true) printf("%d compus\n", i);
        else printf("%d prim\n", i);
}


void construieste_rest(bool *ciur, int n, int curent)
{
    int pid = fork();
    if(pid == 0) // (if in child process)
    {
        if(ciur[curent] == false) // if current is prime
        {
            for(int i = curent * 2; i<=n; i = i + curent)   // mark all its multiples as
                ciur[i] = true;                             // composite
            afis(ciur, n); // I have output here only to verify that everything is good; yet, with each iteration,
            // the array is changed and I do not understand why. From what I know, It should be a copy of the array 
            // in the father process, the father process being the child process in the previous call of the 
            // function...so by my judging, it should work.
            construieste_rest(ciur, n, curent + 2); // repeat
        exit(0);
        }
    }
    else // if in parent
    {
        if(curent * curent >n ) return;
        exit(0);
    }
}

void construieste_ciur(bool *ciur, int n)
{
    ciur[0] = true;
    ciur[1] = true;
    for(int i = 4; i <= n; i = i + 2) ciur[i] = true;
    construieste_rest(ciur, n, 3);
}

int main()
{
    int n;
    scanf("%d", &n);
    bool ciur[Nmax] = {0}; // 0 - prime; 1 - composite
    construieste_ciur(ciur, n);
    afis(ciur, n);
return 0;
}

Трудно добавить пример ввода и вывода здесь, потому что у меня бесконечный l oop. Постараюсь сделать это как-нибудь; если запрашивается ...

Помимо рассматриваемой проблемы, необходимо ли всегда проверять, что дочерний процесс возвращает в качестве состояния выхода?

...