Linux中的clone()函数

int clone(int (*fn)(void *), void *child_stack, int flags, void *arg);

这里fn是函数指针,我们知道进程的4要素,这个就是指向程序的指针,就是所谓的“剧本", child_stack明显是为子进程分配系统堆栈空间(在linux下系统堆栈空间是2页面,就是8K的内存,其中在这块内存中,低地址上放入了值,这个值就是进程控制块task_struct的值),flags就是标志用来描述你需要从父进程继承那些资源, arg就是传给子进程的参数)。下面是flags可以取的值

标志                   含义

 CLONE_PARENT  创建的子进程的父进程是调用者的父进程,新进程与创建它的进程成了“兄弟”而不是“父子”

 CLONE_FS          子进程与父进程共享相同的文件系统,包括root、当前目录、umask

 CLONE_FILES     子进程与父进程共享相同的文件描述符(file descriptor)表

 CLONE_NEWNS  在新的namespace启动子进程,namespace描述了进程的文件hierarchy

 CLONE_SIGHAND  子进程与父进程共享相同的信号处理(signal handler)表

 CLONE_PTRACE  若父进程被trace,子进程也被trace

 CLONE_VFORK    父进程被挂起,直至子进程释放虚拟内存资源

 CLONE_VM          子进程与父进程运行于相同的内存空间

 CLONE_PID         子进程在创建时PID与父进程一致

 CLONE_THREAD   Linux 2.4中增加以支持POSIX线程标准,子进程与父进程共享相同的线程群

下面的例子是创建一个线程(子进程共享了父进程虚存空间,没有自己独立的虚存空间不能称其为进程)。父进程被挂起当子线程释放虚存资源后再继续执行。

与系统调用clone功能相似的系统调用有fork,但fork事实上只是clone的功能的一部分,clone与fork的主要区别在于传递了几个参数,而当中最重要的参数就是conle_flags,下表是系统定义的几个clone_flags标志:
标志 Value 含义
CLONE_VM 0x00000100 置起此标志在进程间共享地址空间
CLONE_FS 0x00000200 置起此标志在进程间共享文件系统信息
CLONE_FILES 0x00000400 置起此标志在进程间共享打开的文件
CLONE_SIGHAND 0x00000800 置起此标志在进程间共享信号处理程序
如果置起以上标志所做的处理分别是:
置起CLONE_VM标志:


本文来自优快云博客,转载请标明出处:http://blog.youkuaiyun.com/haiyan0106/archive/2007/11/19/1891907.aspx

### Linux `clone` 函数使用说明 #### 参数解析 `clone` 是一个功能强大的系统调用,在Linux内核中用于创建新的进程或线程。其函数原型如下: ```c int clone(int (*fn)(void*), void *child_stack, int flags, void *arg, ...); ``` - **fn**: 子进程中要执行的函数指针。 - **child_stack**: 新子进程使用的栈空间起始地址,注意这个栈是从高地址向低地址增长[^3]。 - **flags**: 定义新进程如何共享资源以及行为模式的一组标志位组合。例如CLONE_VM表示共享内存空间;CLONE_FS表示文件系统信息共享等[^4]。 - **arg**: 传递给目标函数`fn`的一个参数。 #### 创建线程的例子 下面展示了一个简单的例子,利用`clone()`来模拟POSIX线程的行为,即多个控制流共享同一虚拟地址空间的情况: ```c #define _GNU_SOURCE #include <sched.h> #include <stdio.h> #include <stdlib.h> static char child_stack[1024 * 1024]; // 每个线程拥有独立的栈区 // 要在线程里运行的任务 static int thread_func(void *args){ printf("Thread %ld is running\n", syscall(SYS_gettid)); return 0; } int main(){ const int num_threads = 5; for (int i=0;i<num_threads;++i){ int res = clone(thread_func, child_stack + sizeof(child_stack), CLONE_VM | CLONE_THREAD, NULL); if(res<0){ perror("Clone failed"); exit(EXIT_FAILURE); } } sleep(1); // 主线程休眠以便让子线程有机会打印消息 return EXIT_SUCCESS; } ``` 这段代码展示了如何通过指定合适的flag选项(这里选择了`CLONE_VM|CLONE_THREAD`),使得由`clone()`产生的新实体能够像传统意义上的“线程”那样工作——它们之间共享相同的地址空间,并且属于同一个线程组。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值