Изменить глобальную переменную из дочернего процесса в Linux - PullRequest
2 голосов
/ 21 февраля 2011

Я родом из C # и у меня немного сложное время с параллелизмом в C. Я не собираюсь вам врать ... Это часть проекта, который я должен сделать для школы.Хотя я профессионально работал с языками высокого уровня, мой старший профессор диссертации бросил нас в тупик, заставив весь класс писать код на C (с которым у большинства из нас практически нет опыта ... :().

В любом случае вернемся к проблеме. У меня есть глобальная целочисленная переменная (начиная с 0), которую нужно одновременно увеличивать на 5 процессов, пока она не достигнет 100 (точнее, 100%).

В основном происходитчто вместо того, чтобы индивидуально изменять завершениеCounter, каждый дочерний процесс делает его копию ...

Есть ли lock(object) или что-то в этом роде, как это доступно в C #? Я пытался использовать двоичный семафор, ноЯ не мог заставить его работать, я еще не играл с общей памятью.

const int THREADCOUNT = 5;
int completionCounter = 0;

int main(int argc, char **argv)
{
    int count = 0;
    pid_t pid;    

    for(count = 0; count<THREADCOUNT; count++)
    {
        if( (pid = fork()) < 0 )
        {
            //error...
            return -1;
        }
        else if( pid == 0 )
        {
            //child;
            while(completionCounter != 100 )
            {
                printf("[%i] process downloading data chunk...", getpid());

                //do stuff here

                completionCounter += 5;

            }
        }
        else
        {
            //parent.
        }
    }    
}

Ответы [ 3 ]

2 голосов
/ 21 февраля 2011

Дочерние процессы не делят переменные со своими родителями. Единственный способ сделать это с разветвленными дочерними процессами - это специально создать и отобразить общую память для хранения значения.

Более разумный способ сделать это - использовать потоки, а не дочерние процессы, но кажется, что вы застряли с заданным вам назначением. В этом случае я бы порекомендовал что-то вроде:

int *x = mmap(0, PAGE_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED|MAP_ANONYMOUS, -1, 0);

перед разветвлением, затем увеличение *x в дочерних процессах ...

НО!

Теперь вам нужно разобраться с синхронизацией. Как есть, вы легко получите пропущенные или повторяющиеся числа в вашем выводе. Поиск мьютексов, совместно используемых процессом POSIX, для начала работы в этом направлении ...

2 голосов
/ 21 февраля 2011

Вы абсолютно правы, того, чего вы хотите, можно достичь с помощью семафоров. Попробуйте man 3 sem_wait, там есть пример.

1 голос
/ 21 февраля 2011

Это вызвано не конфликтной ситуацией, а тем, что при создании нового процесса (что происходит при использовании fork), создается новая копия пространства памяти.Фактически это означает, что вы создаете 5 completionCounter с - по одному для каждого процесса.Используйте pthreads , если хотите, чтобы все разделяли одно и то же пространство памяти.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...