2012-09-19 27 views
0

最近我遇到了一個與多進程共享內存的問題。考慮下面的代碼,主要目的是讓孩子進程由itimer的信號處理器報警,做一些輸出。但令我困惑的是,當我在clone()函數中設置CLONE_VM標誌時,itimer可能出錯,並且輸出文本將填充您的控制檯。CLONE_VM標誌使itimer不準確?

我期望的是:print「--- Alarm!\ n --- ChildThread每秒被喚醒。\ n --- foo = 10」。

實際情況是:重複打印上面的文本非常快。

我想知道如何產生一個子進程,並讓它在此期間共享父進程的內存。非常感謝。

#define _GNU_SOURCE 

#include <stdio.h> 
#include <signal.h> 
#include <sched.h> 
#include <stdlib.h> 
#include <linux/sched.h> 
#include <sys/time.h> 

static volatile int foo = 100; 

int pidChild; 

void AlarmThread(int sig) 
{ 
    printf("---Alarm!\n"); 
    kill(pidChild, SIGCONT); 
} 

int ChildThread(void *arg) 
{ 
    raise(SIGSTOP); 
    while(1) 
    { 
     printf("---ChildThread is awaked.\n"); 
     printf("---foo=%d\n", foo);  // If CLONE_VM is set, this variable may be changed by main thread. 
     raise(SIGSTOP); 
    } 
    return 0; 
} 

int main(int argc, char **argv) 
{ 
    void *stack = malloc(4000) + 4000; 
    struct itimerval itimer; 
    signal(SIGALRM, AlarmThread); 
    pidChild = clone(ChildThread, stack, CLONE_VM | CLONE_SIGHAND, NULL); 
    itimer.it_interval.tv_sec = 1; 
    itimer.it_interval.tv_usec = 0; 
    itimer.it_value = itimer.it_interval; 
    setitimer(ITIMER_REAL, &itimer, NULL); // Set up a 1 tick-per-sec timer. 
    foo = 10; // Test if the child thread shares the main thread's memory. 
    while(1); 
    return 0; 
} 
+0

您是否故意忽略'fork()'和'pthread_create()'是否存在特定的原因? –

+0

因爲我想產生一個kill() - 能夠的PROCESS,所以我不能使用pthread庫。 fork()可能是一種選擇,但在使用它的新進程中調用回調函數似乎更加複雜。由於clone()更具可定製性,所以我決定首先使用它。 – fish47

+2

我會認真對付「克隆」比「fork」更容易的說法...... –

回答

0

但什麼讓我困惑的是,當我在克隆設置CLONE_VM標誌() 功能,itimer可能出錯,輸出文本將東西你 控制檯。

「可能出錯」是什麼意思?發生了什麼?你期望什麼?提問時需要清楚。

CLONE_VM幾乎與itimer無關。事實上,你正在使用這種先進的系統調用,甚至沒有能夠制定你正在做的事情,爲什麼我會相信這是一個學校的任務。

3

我真的會告誡你反對這樣做。共享內存並不僅僅意味着應用程序內存,而且還意味着庫內存(標準庫和您可能使用的任何第三方庫),並且它們可能無法準備讓其他進程破壞其內部數據結構,特別是當他們相信自己正在運行單線程。

如果您只是想要一個進程爲了讓線程具有可打印的PID作爲應用程序的公共可見接口的一部分,爲什麼不讓實際代碼在線程中運行,併產生一個無用的子進程只有for(;;)pause();?然後,讓線程通過退出來響應這個子進程的死亡。