Nano Hash - криптовалюты, майнинг, программирование

Понимание команды fork() Posix API

#include<iostream>
#include<unistd.h>
#include<stdio.h>
using namespace std;
int main()
{
    fork();
    fork();
    fork();
    fork();
    printf("*"); /*This prints 16 stars*/ 
    return 0;
}

Почему при работе с fork() он печатает 16 *?

Я понимаю, что fork() генерирует новый дочерний процесс, который выполняет один и тот же процесс, что объясняет, почему одна вилка генерирует 2 звезды, но с четырьмя вилками она печатает 16, что, как я вижу, удваивается с каждым fork().

Но я не понимаю, почему. Выполняет ли каждый форк нижестоящие функции и параметры?

04.11.2014

  • возможный дубликат Как работает fork()? 05.11.2014
  • И множество других. (Большинство удалено по причине.) 05.11.2014
  • Во всяком случае using namespace std; в программе C? Это достаточно плохо в C++. 05.11.2014
  • Я буду иметь это в виду! 05.11.2014
  • Я собираюсь проголосовать за то, чтобы оставить это открытым, потому что повторяющиеся разветвления в родителях и дочерних элементах увеличиваются с экспоненциальной скоростью. Я думаю, что объяснение поможет ОП и будущим посетителям понять, что на самом деле происходит с суммированием процессов. 22.12.2014

Ответы:


1

Поскольку первая вилка будет разделена на два процесса, второй вызов fork() будет вызываться этими двумя процессами, разделяя эти два процесса на 4. Это будет продолжаться до тех пор, пока в каждом процессе не будут вызваны все вызовы fork(). Таким образом, вы получаете 2^4 = 16 звонков на printf("*")

На «диаграмме» каждая полоса представляет количество процессов, которые выполняются при вызове функции. Таким образом, функция выполняется столько раз, сколько есть баров.

       |   fork()             // The first processes creates a second (2 total)
       |   fork()    |        // Those 2 processes start 2 more       (4 total)
      ||   fork()    ||       // Those 4 processes start 4 more       (8 total)
    ||||   fork()    ||||     // Those 8 processes start 8 more       (16 total) 
||||||||  printf()   |||||||| // resulting in 16 calls to printf()

Выполняет ли каждый форк нижестоящие функции и параметры?

Да, как видно из диаграммы, когда процесс разветвляется, созданный процесс (и тот, который его создал) продолжает выполнение на следующей инструкции после разветвления.

04.11.2014
  • Четкое изображение, вы дали отличное объяснение! 05.11.2014

  • 2

    Когда вы вызываете fork(), он создает новый процесс. Вы дублируете свое приложение, а затем 2 приложения продолжают работать и выполняют новые инструкции после вызова fork()

    printf("i'm the main thread\n");
    fork();
    printf("i'm executed 2 times\n");
    fork(); //this fork is so executed 2 times, so 2 new processes, so 4 processes for all
    printf("i'm excecuted 4 times\n");
    fork(); //this fork is executed 4 times to ! So you have now 8 processes;
    // and etc ..
    fork(); //this fork is executed 8 times, 16 process now !
    printf("*"); // executed 16 times
    

    Новые процессы совместно используют всю память до fork(), старые измененные состояния относятся к текущему потоку. если вы хотите делать другие вещи в зависимости от процесса:

    pid_t p;
    int i = 1;
    p = fork();
    if(p == 0)
    {
        printf("I'm the child\n");
        i = 2;
        exit(0); //end the child process
     }
     printf("i'm the main process\n");
     printf("%d\n", i); //print 1
    
    04.11.2014
  • Обратите внимание, что fork() создает процесс, а не поток. Так что комментарий I'm the main thread немного не тот. 05.11.2014
  • Новые материалы

    Кластеризация: более глубокий взгляд
    Кластеризация — это метод обучения без учителя, в котором мы пытаемся найти группы в наборе данных на основе некоторых известных или неизвестных свойств, которые могут существовать. Независимо от..

    Как написать эффективное резюме
    Предложения по дизайну и макету, чтобы представить себя профессионально Вам не позвонили на собеседование после того, как вы несколько раз подали заявку на работу своей мечты? У вас может..

    Частный метод Python: улучшение инкапсуляции и безопасности
    Введение Python — универсальный и мощный язык программирования, известный своей простотой и удобством использования. Одной из ключевых особенностей, отличающих Python от других языков, является..

    Как я автоматизирую тестирование с помощью Jest
    Шутка для победы, когда дело касается автоматизации тестирования Одной очень важной частью разработки программного обеспечения является автоматизация тестирования, поскольку она создает..

    Работа с векторными символическими архитектурами, часть 4 (искусственный интеллект)
    Hyperseed: неконтролируемое обучение с векторными символическими архитектурами (arXiv) Автор: Евгений Осипов , Сачин Кахавала , Диланта Хапутантри , Тимал Кемпития , Дасвин Де Сильва ,..

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

    Обеспечение масштабируемости LLM: облачный анализ с помощью AWS Fargate и Copilot
    В динамичной области искусственного интеллекта все большее распространение получают модели больших языков (LLM). Они жизненно важны для различных приложений, таких как интеллектуальные..