C 克隆虚拟机标志使itimer不准确?

C 克隆虚拟机标志使itimer不准确?,c,linux,multithreading,multiprocessing,system-calls,C,Linux,Multithreading,Multiprocessing,System Calls,最近我遇到了一个关于多进程共享内存的问题。考虑下面的代码,主要目的是让子进程对iTime'的信号处理程序感到惊慌,做一些输出。但让我困惑的是,当我在CLONE()函数中设置CLONE_VM标志时,itimer可能会出错,输出文本会塞满控制台 我期望的是:打印”--报警!\n--ChildThread被唤醒。\n--foo=10“每秒。 实际情况是:非常快地重复打印上面的文本。 我想知道如何生成一个子进程,同时让它共享其父进程的内存。非常感谢 #define _GNU_SOURCE #inclu

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

我期望的是:打印”--报警!\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;
}
定义GNU源
#包括
#包括
#包括
#包括
#包括
#包括
静态挥发性int foo=100;
int pidChild;
无效报警线程(int sig)
{
printf(“---报警!\n”);
杀死(pidChild,SIGCONT);
}
int ChildThread(void*arg)
{
升起(停止);
而(1)
{
printf(“--ChildThread被唤醒。\n”);
printf(“--foo=%d\n”,foo);//如果设置了CLONE\u VM,则主线程可能会更改此变量。
升起(停止);
}
返回0;
}
int main(int argc,字符**argv)
{
void*stack=malloc(4000)+4000;
结构itimerval itimer;
信号(信号、报警线程);
pidChild=clone(ChildThread,stack,clone_VM | clone_signand,NULL);
itimer.it_interval.tv_sec=1;
itimer.it_interval.tv_usec=0;
itimer.it_值=itimer.it_间隔;
setitimer(ITIMER_REAL,&ITIMER,NULL);//设置每秒1个刻度的计时器。
foo=10;//测试子线程是否共享主线程的内存。
而(1),;
返回0;
}
但让我困惑的是,当我在CLONE()中设置CLONE_VM标志时 函数时,itimer可能出错,输出文本将填充您的 控制台

“可能出错”是什么意思?怎么搞的?你期待什么?问问题时,你需要清楚

克隆虚拟机与itimer几乎没有任何关系。事实上,您使用的是这样的高级系统调用,甚至无法确定您正在尝试做什么,以及为什么让我相信这是一项学校作业

但让我困惑的是,当我在CLONE()中设置CLONE_VM标志时 函数时,itimer可能出错,输出文本将填充您的 控制台

“可能出错”是什么意思?怎么搞的?你期待什么?问问题时,你需要清楚


克隆虚拟机与itimer几乎没有任何关系。事实上,您正在使用这样的高级系统调用,甚至无法确定您正在尝试做什么,以及为什么让我相信这是一项学校作业。

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


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

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


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

出于特定原因,您是否故意忽略了
fork()
pthread\u create()
的存在?因为我想生成一个kill()可执行的进程,所以我不能使用pthread lib。fork()可能是一种选择,但在新流程中使用它调用回调函数似乎更复杂。由于clone()更具可定制性,所以我决定首先使用它。我会认真反对
clone
fork
容易的说法。我只想生成一个进程,它可以:1.kill()-能够2.与其他进程一起运行3.共享主进程的内存4.只调用特定的回调函数。有什么好主意吗?谢谢。您是否出于特定原因故意忽略了
fork()
pthread\u create()
的存在?因为我想生成一个kill()可执行的进程,所以无法使用pthread lib。fork()可能是一种选择,但在新流程中使用它调用回调函数似乎更复杂。由于clone()更具可定制性,所以我决定首先使用它。我会认真反对
clone
fork
容易的说法。我只想生成一个进程,它可以:1.kill()-能够2.与其他进程一起运行3.共享主进程的内存4.只调用特定的回调函数。有什么好主意吗?谢谢