提问人:rempas 提问时间:10/18/2023 更新时间:10/18/2023 访问量:152
Linux:使用“clone3”和“waitid”
Linux: Using "clone3" and "waitid"
问:
我正在尝试使用“clone3”系统调用来了解分叉/克隆过程。我已经阅读了手册页来理解它。除了手册页之外,我只能找到一个如何在线(在互联网上)使用它的示例,它似乎不起作用。此外,该示例使用“waitpid”libc 函数而不是我想使用的“waitid”系统调用。总之,我修改了该示例以将其“转换”为以下代码:
#ifndef _GNU_SOURCE
#define _GNU_SOURCE 1
#endif
#include <bits/types/struct_rusage.h>
#include <errno.h>
#include <linux/sched.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/syscall.h>
#include <sys/wait.h>
#include <unistd.h>
#ifndef CLONE_PIDFD
#define CLONE_PIDFD 0x00001000
#endif
#ifndef __NR_clone3
#define __NR_clone3 -1
struct clone_args {
__aligned_u64 flags;
__aligned_u64 pidfd;
__aligned_u64 child_tid;
__aligned_u64 parent_tid;
__aligned_u64 exit_signal;
__aligned_u64 stack;
__aligned_u64 stack_size;
__aligned_u64 tls;
};
#endif
static pid_t sys_clone3(struct clone_args *args) { return syscall(__NR_clone3, args, sizeof(struct clone_args)); }
static int sys_waitid(
idtype_t type, id_t id, siginfo_t* info,
struct rusage* usage, int options)
{
return syscall(247, type, id, info, usage, options);
}
int value = 10;
int main(int argc, char *argv[]) {
struct clone_args args = {
.flags = CLONE_VM,
.exit_signal = SIGCHLD,
};
int pid = sys_clone3(&args);
if (pid < 0) {
fprintf(stderr, "%s - Failed to create new process\n", strerror(errno));
exit(EXIT_FAILURE);
}
if (pid == 0) {
printf("Child process with pid %d\n", getpid());
value = 20;
printf("Value changed!");
exit(EXIT_SUCCESS);
}
printf("Parent process received child's pid %d\n", pid);
siginfo_t info;
struct rusage usage;
int wait_status = sys_waitid(P_ALL, 0, &info, &usage, __WALL);
if (wait_status == -1) {
fprintf(stderr, "Failed to wait on child process (%d)\n", errno);
exit(EXIT_FAILURE);
}
printf("Tha value is: %d\n", value);
return 0;
}
然而,它不起作用。由于某种原因,克隆进程的块似乎没有执行。此外,如果我连续多次运行该程序,在某些时候,它将无法等待退出代码为“22”的进程。调用错误代码,这意味着 “waitid” 的选项无效(如手册页所述)。但是,这怎么可能不是每次都被执行,而是随机发生呢?我很困惑......EINVAL
我认为这也是一个很好的问题,因为网上关于“clone3”的信息很少。还应该指出的是,我特别需要这两个。我正在编写一个系统的库,我想学习如何使用它们。此外,我正在创建自己的“waitid”版本,因为“libc”版本没有使用“rusage”结构,所以我想 100% 确定没有其他我看不到的事情发生。谢谢!
我希望程序执行新创建的线程的块。
答: 暂无答案
评论