先这几天搞多进程以及多线程通信,怎奈以前没有深接触,所以这里总结一下。
#include <sys/types.h>
#include <stdio.h>
#include <stdlib.h>
int glob = 6;
char buf[] = "a write to stdout/n";
int main()
{
int var;
pid_t pid;
var = 88;
fprintf(stderr, "%s", buf);
printf("before fork/n");
if(( pid = fork() ) < 0 )
{
fprintf(stderr, "fork error/n");
}
else if(pid == 0)
{
glob++;
var++;
printf("child process/n");
printf("pid = %d, father pid = %d, glob = %d, var = %d/n", getpid(), getppid(), glob, var);
exit(0);
}
else
{
sleep(2);
printf("father process/n");
printf("pid = %d, father pid = %d, glob = %d, var = %d/n", getpid(), getppid(), glob, var);
}
return 0;
}
运行结果为:
a write to stdout
before fork
child process
pid = 5139, father pid = 5138, glob = 7, var = 89
father process
pid = 5138, father pid = 2936, glob = 6, var = 88
为什么子进程没有修改全局变量和主进程的局部变量的值?
因为进程之间都是有独立的占用内存,子进程只是把父进程的相关变量值复制到了自己的变量中,所以这里修改的都是自己内存区域的变量的值。
为什么ifelse都执行了?
因为fork()之后出现了两个进程,而两个进程除了id不一样代码都是一样的,此时你就要把上面的代码想象成两份(实际就是两份),在主进程里面,fork()函数返回的是子进程的id,那么就执行else部分,而在子进程里面,fork返回的就是0。所以看上去就像是fork返回了两次值一样,实际是两份代码了。fork针对不同的进程返回不同的值。
还有一段代码
#include <stdlib.h>
#include <unistd.h>
#include <iostream>
using namespace std;
int j = 0;
/*
*
*/
int main(int argc, char** argv) {
signal(SIGCHLD,SIG_IGN); //avoid zombie process
int *i;
i = &j;
int k=0;
pid_t pid,pid1,pid2;
cout < <"this is at beginning, pointer i is" < <i < <endl;
sleep(1);
pid = fork();
if(pid <0)
{
cout < <"create childprocess error!" < <endl;
}
else if (pid == 0)
{
cout < <"for childprocess,pointer i = " < <i < <endl;
for(k;k <10;k++)
{
(*i)++;
cout < <"for childprocess,j = " < <*i < <endl;
}
}
else if(pid > 0)
{
sleep(5);
cout < <"for fatherprocess, j = " < <*i < <endl;
cout < <"for fatherprocess, i = " < <i < <endl;
}
return (EXIT_SUCCESS);
}
执行结果是:
this is at beginning, pointer i is0x804a0d4
for childprocess,pointer i = 0x804a0d4
for childprocess,j = 1
for childprocess,j = 2
for childprocess,j = 3
for childprocess,j = 4
for childprocess,j = 5
for childprocess,j = 6
for childprocess,j = 7
for childprocess,j = 8
for childprocess,j = 9
for childprocess,j = 10
for fatherprocess, j = 0
for fatherprocess, i = 0x804a0d4
可以看到指针指向的是相同的地址,为什么相同内存地址存储的数据是不一样的呢?
这是因为fork后两个进程有各自独立的内存空间,但是用的都是虚拟的内存空间,所以在子进程中的0x804a0d4地址与父进程的0x804a0d4虽然值相同,但是这是在自己的内存区域的值,并不是实际的物理内存的地址,当映射到物理内存以后实际上不同的区域。看看更专业的解释:
程序里看到的指针的值,比如0x804a0d4,都是虚拟地址。每个进程都有独立的4G的虚拟地址空间,映射到不同的物理空间。比如我现在同时运行IE和QQ,他们都有可能访问各自的0x804a0d4这个虚拟地址,但是映射之后的物理内存就不会是同一个地址。