学系统编程都会学到进程与及线程,在学习Linux编程过程中,最大的困难花时间最多的莫过于进程那一块,包括进程的环境,进程的控制,进程间通信,进程共享内存等。
fork()是linux生成一个新进程的函数,在《unix环境高级编程》书中P172页是这样描述的:子进程是父进程的副本。例如,子进程获得父进程的数据空间, 堆和栈的副本。注意,这是子进程所拥有的副本。父、子进程并不共享这些存储空间部分。父子进程共享正文段。
既然子进程是父进程的一个副本,获得父进程的数据空间,但又不是共享的,那么是否子进程具有独立的物理内存空间呢?父进程中的一个变量a是否还有另一个副本存在子进程空间物理内存里,也即在父、子进程里分别执行printf(“a address: %lx”, &a)会输出不同的值呢?
[@more@] 于是写了一段测试程序,发现两个变量物理地址一样的,并且未初始化数据的地址也一,IPC共享内存段地址一样,动态分配堆空间也一样,纳闷了很久,为什么呢?
从输出的结果来看,变量在物理内存只分配了一次,那么子进程的变量副本又是如何实现的呢?不另外分配一块内存来存储它的变量, 那怎样实现和父进程的变量取不同的值呢?
代码如下:
#include "apue.h"
#include
#define ARRAY_SIZE 40000
#define MALLOC_SIZE 100000
#define SHM_SIZE 100000
#define SHM_MODE 0600 /* user read/write */
char array[ARRAY_SIZE]; /* uninitialized data = bss */
int
main(void)
{
int shmid;
int n = 1;
char *ptr, *shmptr;
pid_t pid;
if ((shmid = shmget(IPC_PRIVATE, SHM_SIZE, SHM_MODE)) < 0)
err_sys("shmget error");
if ((shmptr = shmat(shmid, 0, 0)) == (void *)-1)
err_sys("shmat error");
if ((ptr = malloc(MALLOC_SIZE)) == NULL)
err_sys("malloc error");
TELL_WAIT();
if((pid = fork()) < 0)
err_sys("fork error");
else if(pid == 0)
{
n = 5;
printf("pid = %d ", getpid());
printf("n = %d,stack around %lx ", n, (unsigned long)&n);
printf("shared memory attached from %lx to %lx ",
(unsigned long)shmptr, (unsigned long)shmptr+SHM_SIZE);
printf("malloced from %lx to %lx ", (unsigned long)ptr,
(unsigned long)ptr+MALLOC_SIZE);
printf("array[] from %lx to %lx ", (unsigned long)&array[0],
(unsigned long)&array[ARRAY_SIZE]);
TELL_PARENT(pid);
exit(0);
}
WAIT_CHILD();
printf(" pid=%d ", getpid());
printf("n = %d, stack around %lx ", n, (unsigned long)&n);
printf("shared memory attached from %lx to %lx ",
(unsigned long)shmptr, (unsigned long)shmptr+SHM_SIZE);
printf("malloced from %lx to %lx ", (unsigned long)ptr,
(unsigned long)ptr+MALLOC_SIZE);
printf("array[] from %lx to %lx ", (unsigned long)&array[0],
(unsigned long)&array[ARRAY_SIZE]);
if (shmctl(shmid, IPC_RMID, 0) < 0)
err_sys("shmctl error");
exit(0);
}
来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/7406370/viewspace-926598/,如需转载,请注明出处,否则将追究法律责任。
转载于:http://blog.itpub.net/7406370/viewspace-926598/