CLONE_VM标志使itimer不准确?

时间:2012-09-19 11:42:33

标签: c linux multithreading multiprocessing system-calls

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

我的期望是:打印“---闹钟!\ n --- ChildThread被唤醒。\ n = foo = 10”每秒。

实际情况是:重复快速打印上面的文字。

我想知道如何生成一个子PROCESS,让它同时分享它的父内存。非常感谢。

#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;
}

2 个答案:

答案 0 :(得分:3)

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

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

答案 1 :(得分:0)

  

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

“可能出错”是什么意思?发生了什么?你有什么期望?在提问时你需要清楚。

CLONE_VM几乎与itimer无关。事实上,你使用这样的高级系统调用,甚至无法制定你想要做的事情以及为什么让我相信这是一项学校作业。