【问题标题】:clone() syscall in C and sharingC 中的 clone() 系统调用和共享
【发布时间】:2012-09-08 21:55:28
【问题描述】:

我正在尝试使用 clone() 系统调用来创建一个与父进程共享资源的线程。 在书中我读到,如果我使用以下标志,我将能够这样做: 克隆虚拟机 |克隆文件 |克隆_SIGHAND | CLONE_FS

但似乎没有共享变量。

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <linux/sched.h>
#include <string.h>
#define STACK_SIZE 65536
#define BUFSIZE 200
int n = 5;
int Child(void *);
int main() {
    pid_t pid;
    char *stack;
    stack = malloc(STACK_SIZE);
    pid = clone(Child,stack + STACK_SIZE, CLONE_SIGHAND|CLONE_FS|CLONE_VM|CLONE_FILES);
    wait(NULL);
    char buf[BUFSIZE];
    sprintf(buf,"Back to parent: Value of n: %d\n",n);
    write(1,buf,strlen(buf));
    return 0;
}
int Child(void *args) {
    n += 15;
    char buf[BUFSIZE];
    sprintf(buf,"In child: Value of n: %d\n",n); 
    write(1,buf,strlen(buf));
}

输出也不断变化。我很困惑。

【问题讨论】:

  • 听起来你可以只使用pthreads。真的有必要手动使用特定于 Linux 的、非常复杂的系统调用吗?
  • 确实可以。我只是想看看 clone() 是如何工作的。

标签: c linux clone fork


【解决方案1】:
int n = 5;
int Child(void *);
int main() {
    int n = 5;

您有两个名为n 的变量。 Child 对全局变量进行操作,但 main 使用在其范围内定义的变量。

您还应该将您的wait 调用更改为waitpid(-1, NULL, __WALL),否则您实际上不会等待克隆的进程。 (或者您可以将|SIGCHLD 添加到克隆选项中。)

来自clone(2) 文档:

标志的低字节包含发送到的终止信号的编号 孩子去世时的父母。如果这个信号被指定为任何其他 比 SIGCHLD,则父进程必须指定 __WALL 或 __WCLONE 使用 wait(2) 等待孩子时的选项。如果没有指定信号, 那么当子进程终止时,父进程不会收到信号。

【讨论】:

  • 哎呀,我在调试过程中添加了它并忘记删除它。但是,当我删除它时,输出仍然相同。
  • 编辑回来。输出仍然是相同的。似乎孩子只获得了全局变量的副本,而不是全局变量本身。所以资源根本没有共享?
  • 您的等待调用实际上并没有等待任何东西。
  • 它在文档中。 clone 是一个相当复杂的调用,请仔细阅读手册页。
猜你喜欢
  • 1970-01-01
  • 2020-09-14
  • 2011-08-04
  • 2016-02-09
  • 1970-01-01
  • 2010-12-30
  • 2012-09-04
  • 2015-11-17
  • 1970-01-01
相关资源
最近更新 更多