简体   繁体   English

视觉上当您使用&符号调用相同的进程时会发生什么

[英]Visually what happens when you call same process with ampersand

I am playing with ampersand “&” . 我正在玩ampersand “&” I understand that in bash shell script the 我理解在bash shell脚本中

ampersand is used to fork processes but will run in the background . &符号用于分叉进程,但将在后台运行。 This is useful because it allows you to get your prompt back immediately , and run the process in the background . 这是有用的,因为它可以让你立即切换回之前的提示,并在后台运行的进程

Please observe the following code: 请遵守以下代码:

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

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++);
}

After successful compilation, I run the code with: 编译成功后,我运行代码:

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

Output of first run: 首次输出的输出:

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

Output of second run: 第二轮输出:

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

Observations: 观察:

  • Some print statements appear in different order because each process is running simultaneously. 某些打印语句以不同的顺序出现,因为每个进程同时运行。
  • Address of variable x is the same on all instances because it's a global variable. 变量x的地址在所有实例上都是相同的,因为它是一个全局变量。
  • Value of x is the same in all instances because it gets reset every time to 5. x的值在所有实例中都是相同的,因为它每次都会重置为5。
  • Variable y is only local to main(), therefore its address will be unique in each process. 变量y只是main()的本地,因此它的地址在每个进程中都是唯一的。

Here are my questions: 这是我的问题:

  1. The reason why some print statements appear in different order are determined by which process was started first by the OS scheduler? 某些打印语句以不同顺序出现的原因取决于OS调度程序首先启动哪个进程?
  2. Since variable x is global and seems to keep the same address in all runs/instances. 由于变量x是全局的,并且似乎在所有运行/实例中保持相同的地址。 Why isn't its value shared among processes after the auto increment? 在自动增量之后,为什么它的值不在进程之间共享? Why doesn't ANY process print an incremented value of x? 为什么任何进程都不打印x的递增值?

Each process has its own address space in virtual memory (thanks to the processor's MMU ). 每个进程虚拟内存 都有自己的地址空间 (归功于处理器的MMU )。 So variable x is not global to your 3 processes; 所以变量x对于你的3个过程来说不是全局的 ; every process has its own x ; 每个进程都有自己的x ; so address 0x601058 (the printed address of x ) in process 4436 is not the same location as the "same" address 0x601058 in process 4435. 因此,过程4436中的地址0x601058( x的打印地址)与过程4435中的“相同”地址0x601058不是相同的位置。

So (virtual) memory is specific to every process. 因此(虚拟)内存特定于每个进程。 A process can change its address space using mmap(2) . 进程可以使用mmap(2)更改其地址空间。 You could use some advanced techniques to set up some shared memory between several processes (but learn more some Linux programming before). 您可以使用一些高级技术在多个进程之间设置一些共享内存 (但之前要了解一些Linux编程)。 See shm_overview(7) & sem_overview(7) . shm_overview(7)sem_overview(7) You should not (as a newbie) want to use shared memory, because of synchronization issues. 由于同步问题,您不应该(作为新手)想要使用共享内存。

Read Advanced Linux Programming , it has several chapters related to your questions. 阅读高级Linux编程 ,它有几个与您的问题相关的章节。

A multi-threaded process has several threads sharing the same address space (and other things like current directory, opened file descriptors, etc...). 多线程进程有几个线程共享相同的地址空间(以及其他东西,如当前目录,打开的文件描述符等...)。 Read also some POSIX thread (aka pthread) tutorial . 另请阅读一些POSIX线程(又名pthread)教程 Each thread has its own call stack . 每个线程都有自己的调用堆栈

Notice that addresses might not be reproducible from one run to the next one, because of ASLR . 请注意,由于ASLR ,地址可能无法从一次运行再现到下一次运行。

The Linux kernel has a scheduler working on tasks . Linux内核有一个处理任务调度 程序 A scheduled task is either a thread or a (single-threaded) process. 计划任务是线程或(单线程)进程。 The scheduler may preempt tasks at arbitrary moments, and on a multi-core processor you may have several tasks running in parallel (on different cores). 调度程序可以在任意时刻抢占任务,而在多核处理器上,您可能有多个并行运行的任务(在不同的核心上)。

You could also play (on Linux) with proc(5) . 您也可以使用proc(5)播放(在Linux上 If you let your processes sleep eg 10 seconds, you could type (eg in a different terminal) cat /proc/4436/maps while your process 4436 is still running (or asleep). 如果让你的进程休眠10秒钟,你可以在进程4436仍在运行(或睡眠)时键入(例如在不同的终端中) cat /proc/4436/maps

You might also play with strace(1) , maybe try strace a.out to see the relevant syscalls(2) . 您也可以使用strace(1) ,也可以尝试strace a.out来查看相关的系统调用(2)

Of course, read several times the documentation of fork(2) and execve(2) 当然,阅读几次fork(2)execve(2)的文档

Since the bash shell is free software , you could study its source code. 由于bash shell是免费软件 ,你可以研究它的源代码。 It does call fork a lot! 它调用fork了很多!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 在现有变量上调用malloc时会发生什么? - What happens when you call malloc on an existing variable? 用负参数调用glClearColor时会发生什么? - What happens when you call glClearColor with a negative argument? 当你调用 read() 的长度太大时会发生什么? - What happens when you call read() with length that is too large? 调用方法/函数时汇编语言会发生什么? - What happens in assembly language when you call a method/function? 视觉上For循环中fork()会发生什么 - Visually what happens to fork() in a For Loop 当您写入具有相同配置的寄存器时会发生什么? - What happens when you write to a register with the same configuration? 如果我在使用 PTHREAD_PROCESS_SHARED 时不调用 pthread_mutex_destroy 会发生什么 - What happens if I do not call pthread_mutex_destroy when using PTHREAD_PROCESS_SHARED 文件系统已满时进程会发生什么 - What happens to a process when the filesystem is full 当您对与 dup2() 复制的管道文件描述符调用 close() 时会发生什么? - What happens when you call close() on a pipe file descriptor that was duplicated with dup2()? 当您调用带有返回值的函数而不将其分配给任何变量时会发生什么? - What happens when you call a function with return value without assigning it to any variable?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM