0

最近我遇到一个关于与多进程共享内存的问题。考虑下面的代码,主要目的是让子进程被定时器的信号处理程序报警,做一些输出。但令我困惑的是,当我在 clone() 函数中设置 CLONE_VM 标志时,itimer 可能会出错,并且输出文本会填满你的控制台。

我期望的是:每秒打印“---Alarm!\n---ChildThread is awaked.\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;
}
4

2 回答 2

3

我真的会警告你要这样做。共享内存不仅仅意味着应用程序内存,还包括库内存(标准库和您可能使用的任何第三方库),并且它们可能还没有准备好让其他进程破坏其内部数据结构,尤其是当它们认为自己会破坏其内部数据结构时运行单线程。

如果您只是想要一个进程,以便将线程的可终止 PID 作为应用程序的公开可见界面的一部分,为什么不让实际代码在线程中运行,并生成一个无用的子进程,它什么都不做for(;;)pause();呢?然后,让线程通过退出来响应这个子进程的死亡。

于 2012-09-19T18:16:36.837 回答
0

但令我困惑的是,当我在 clone() 函数中设置 CLONE_VM 标志时,itimer 可能会出错,并且输出文本会填满你的控制台。

“可能出错”是什么意思?发生了什么?你期待什么?提问的时候需要说清楚。

CLONE_VM 几乎与 itimer 无关。您正在使用像这样的高级系统调用,甚至无法制定您正在尝试做什么以及为什么让我相信这是一项学校作业。

于 2012-09-19T14:34:23.500 回答