C ветвление, имеющее дело с глобальной переменной

Я не понимаю вывода этой программы:

#include <pthread.h>
#include <stdio.h>
#include <unistd.h>

int i = 0;

int main()
{
    while(i<3)
    {
        fork();

        printf("%d\n",i);
        ++i;
    }
}

Вывод:

0
1
2
2
1
2
0
1
2
2
2
1
2
2

Может нравиться, что кто-то говорит мне, как я должен заняться этой проблемой, чтобы полностью понять, почему я получаю этот вывод?

8
задан Paul R 16 June 2015 в 04:48
поделиться

5 ответов

Измените свой код к этому, и выход должен сделать намного больше смысла:

#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>

int i = 0;

int main()
{
    while (i < 3)
    {
        fork();
        printf("pid = %d, i = %d\n", getpid(), i);
        ++i;
    }
    return 0;
}
16
ответ дан 3 November 2019 в 12:13
поделиться

У меня была такая же проблема, даже с псевдонимами Extern, а I поднял его как ошибка компилятора . Обходной путь в настоящее время - отказаться от синтаксиса метода расширения.

Ошибка исправлена ​​для Visual Studio 2010.

-121--1415739-

При вилке () в своем текущем состоянии создается полная копия текущего процесса. Это означает, что ваш начальный процесс создаст три новых процесса, которые находятся в центре цикла, с I , соответственно 0, 1 и 2 в каждом из них. Он также распечатает свои собственные значения I .

Каждый из его детей будет продолжать петлю из вилков () вызова путем печати его начала I значение, увеличение и циклов. Это означает, что дети 0 будут печатать 0, 1, а 2 и порождать двух новых детей, с «первоначальными» значениями I 1 и 2. Дети 1 будут печатать 1 и 2 и порождать еще одну детей, С «первоначальным» значением I 2. Дети 2 будет печатать 2 и оставить петлю.

Если вы продолжите это рассуждение, вы придете к выводу, что в общей сложности два 0, четыре 1 и восемь 2-х годов будут напечатаны. Но, поскольку порядок исполнения зависит от того, как ОС расписаны одновременные процессы, вы не можете иметь гарантии на заказ напечатаны.

5
ответ дан 3 November 2019 в 12:13
поделиться

Форк сделает копию процесса. Независимая копия процесса. Таким образом, если глобальная переменная содержится 3 в то время, когда вы вилее, каждая копия процесса становится самой собственной 3. И если они изменяют, их модификации полностью независимы.

25
ответ дан 3 November 2019 в 12:13
поделиться

Это что-то вроде...

 1 (main) instance, i = 0(unforked)
 fork() > 2 instances, with i's = 0(forked), and 0(forked)
0 output from main instance, increments its i, 2 instances with i = 1u, 0f
 main instance forks, there's 3 instances with i's 1f, 1f, 0f
1 output from main instance, increments its i, 3 instances with i = 2u, 1f, 0f
 main instance forks, there's 4 instances with i's 2f, 2f, 1f, 0f
2 output from main instance, increments its i, 4 instances with i = 3u, 2f, 1f, 0f
 main instance then dies, 3 instances with i = 2f, 1f, 0f
2 output from next instance, increments its i, 3 instances with i = 3u, 1f, 0f
 next instance then dies, 2 instances with i = 1f, 0f
1 output from next instance, increments its i to 2, 2 instances with i = 2u, 0f

...и т.д.

Порядок вывода процессов, однако, не определен, поэтому вы, скорее всего, не увидите каждый раз один и тот же вывод, и даже если вы это сделаете, вы можете это гарантировать.

Как говорили другие люди, каждый процесс имеет свое собственное глобальное "i", за которым он следит, и его значение - это просто значение "i" процесса вилки в развилке.

2
ответ дан 3 November 2019 в 12:13
поделиться

Add Web Reference - это устаревшая технология ASP.NET webservices (ASMX) в старом стиле (использующая для своих вещей только GroupSerializer) - при этом вы получаете клиент ASMX для веб-службы ASMX. Это можно сделать практически в любом проекте (Web App, Web Site, Console App, Winforms - вы его называете).

Добавить ссылку на услугу - это новый способ сделать это, добавив ссылку на услугу WCF, которая дает вам гораздо более совершенную, гораздо более гибкую модель услуги, чем просто простой старый материал ASMX.

Поскольку вы не готовы к переходу на WCF, вы также можете добавить веб-ссылку старого образца, если действительно необходимо: при выполнении «Add Service Reference» в появившемся диалоговом окне нажмите кнопку [Advanced] в левом углу кнопки:

alt text

и в следующем появившемся диалоговом окне нажмите кнопку [Add Web Reference] внизу.

-121--718741-

Лучший способ выполнить то, что вы хотите, это использовать http _ build _ query () .

-121--2570686-

Попробуйте использовать pthreads, если вы хотите создать поток внутри процесса для параллельного программирования. Требуемая функция pthread_create и pthread_join для приведения в порядок позже.

Примерно так:

#include <pthread.h>
#include <stdio.h>
#include <unistd.h>
#include <malloc.h>


int i = 0;

void *threadFunc(void *arg) 
{
    printf("%d\n",i);
}

int main()
{
    int j = 0;  
    int returnValue = 0;
    pthread_t* myThread = (pthread_t*) calloc(3, sizeof(pthread_t));;

    while(i < 3)
    {

        returnValue = pthread_create(&myThread[i], NULL, threadFunc, NULL);
        printf("main thread: %d\n",i);
        i++;

    }


    for(j = 0; j < 3; j++)
    {
        pthread_join(myThread[j], NULL); 

    }

    return 0;
}

Но, возможно, нет, в зависимости от ваших реальных потребностей.

3
ответ дан 3 November 2019 в 12:13
поделиться
Другие вопросы по тегам:

Похожие вопросы: