Intereting Posts
Ubuntu 17.10 – не удалось забрать устройства Bluetooth после обновления Apparmor не запускается с ошибкой ядра LSM как обновить сервер передач на Ubuntu 11.10 В чем разница между #! / Bin / sh и #! / Bin / bash? Как Ubuntu зарабатывает деньги? Будет ли в будущем лучшая альтернатива, чем Uniy? Обновление сообщения об ошибке dpkg с ubuntu с 15.04 по 15.10 Пропуск получения сконфигурированного файла «main / binary-i386 / Packages» в качестве хранилища «xxx» не поддерживает архитектуру «i386» Как перенести файлы с Ubuntu на Android через Wi-Fi? Как узнать, какие плагины я установил для Nautilus? Каждый раз, когда я перезагружаюсь, я теряю свои приложения в Unity! Недопустимый аргумент – сканер Brother не работает после обновления (драйвер brscan2) Закончено с kde 4.x (плазма 4) вместо плазмы 5.4 от Ubuntun 14.04 Если компания использует ubuntu на своих серверах / настольных компьютерах, она должна платить? Средство просмотра изображений WebM

Визуально, что происходит, когда вы вызываете тот же процесс с амперсандом

Я играю с ampersand “&” . Я понимаю, что в сценарии оболочки bash

Амперсанд используется для процессов вилки, но работает в фоновом режиме . Это полезно, потому что это позволяет сразу же вернуть ваш запрос и запустить процесс в фоновом режиме .

Соблюдайте следующий код:

 #include  #include  int x=5; void main() { int pid = getpid(); int y=6; printf("[%d] [%p] x = %d\n", pid, &x, x++); printf("[%d] [%p] y = %d\n", pid, &y, y++); } 

После успешной компиляции я запускаю код с помощью:

 > ./a.out & ./a.out & ./a.out 

Выход первого запуска:

 [4436] [0x601058] x = 5 [4435] [0x601058] x = 5 [4436] [0x7fff2d481bd8] y = 6 [4435] [0x7fff7ecadd88] y = 6 [4437] [0x601058] x = 5 [4437] [0x7fff6e0741d8] y = 6 

Выход второго запуска:

 [4469] [0x601058] x = 5 [4469] [0x7fffa00048b8] y = 6 [4470] [0x601058] x = 5 [4470] [0x7fffd447a798] y = 6 [4468] [0x601058] x = 5 [4468] [0x7fffc35dc7b8] y = 6 

Замечания:

  • Некоторые операторы печати отображаются в другом порядке, поскольку каждый процесс выполняется одновременно.
  • Адрес переменной x одинаковый для всех экземпляров, потому что это глобальная переменная.
  • Значение x одинаково во всех случаях, потому что каждый раз он сбрасывается до 5.
  • Переменная y является только локальной для main (), поэтому ее адрес будет уникальным в каждом процессе.

Вот мои вопросы:

  1. Причина, по которой некоторые заявления печати отображаются в другом порядке, определяется тем, какой процесс был запущен сначала планировщиком ОС?
  2. Поскольку переменная x является глобальной и, кажется, сохраняет один и тот же адрес во всех экземплярах / экземплярах. Почему его ценность не распределяется между процессами после автоматического увеличения? Почему ни один процесс не обрабатывает увеличенное значение x?

Каждый процесс имеет собственное адресное пространство в виртуальной памяти (благодаря MMU процессора). Таким образом, переменная x не является глобальной для ваших 3 процессов; каждый процесс имеет свой собственный x ; поэтому адрес 0x601058 (печатный адрес x ) в процессе 4436 не совпадает с тем же «адресом» 0x601058 в процессе 4435.

Таким образом (виртуальная) память специфична для каждого процесса. Процесс может изменить его адресное пространство с помощью mmap (2) . Вы можете использовать некоторые продвинутые методы для настройки некоторой разделяемой памяти между несколькими процессами (но прежде всего узнайте о некоторых программах Linux). См. Shm_overview (7) & sem_overview (7) . Вы не должны (как новичок) хотеть использовать разделяемую память из-за проблем с синхронизацией.

Прочитайте Advanced Linux Programming , у него есть несколько глав, связанных с вашими вопросами.

Многопоточный процесс имеет несколько streamов, разделяющих одно и то же адресное пространство (и другие вещи, такие как текущий каталог, открытые дескрипторы файлов и т. Д.). Также прочитайте учебник по POSIX-streamу (aka pthread) . Каждый stream имеет свой собственный стек вызовов .

Обратите внимание, что адреса могут не воспроизводиться с одного запуска на следующий, из-за ASLR .

Ядро Linux имеет планировщик, работающий над задачами . Запланированная задача – это нить или (однопоточный) процесс. Планировщик может выполнять задачи в произвольные моменты, а на многоядерном процессоре у вас может быть несколько задач, выполняющихся параллельно (на разных ядрах).

Вы также можете играть (в Linux) с proc (5) . Если вы позволяете вашим процессам спать, например, 10 секунд, вы можете ввести (например, в другой терминал) cat /proc/4436/maps пока ваш процесс 4436 все еще работает (или спит).

Вы также можете играть с strace (1) , возможно, попробуйте strace a.out чтобы увидеть соответствующие системные вызовы (2) .

Конечно, прочитайте несколько раз документацию о вилке (2) и execve (2)

Поскольку shell bash является свободным программным обеспечением , вы можете изучить ее исходный код. Это очень часто вызывает fork !