linux fork程式空間問題

longtrue發表於2007-07-14

學系統程式設計都會學到程式與及執行緒,在學習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/,如需轉載,請註明出處,否則將追究法律責任。

相關文章