Linux--进程(clone)
1 clone:产生线程,可以对父子进程间的共享、复制进行精确控制。也可以允许新创建的进程共享调用它的进程(通常是父进程)的部分资源,比如内存空间、文件描述符表、信号量等,具体需要共享那些内容可以通过clone的flag参数设置。
man clone

用于创建一个新的子进程,类似fork(2)。与fork(2)相比,它可以更精确地控制调用进程和子进程之间的执行上下文细节。
1> fn 新创建进程的入口函数;
2> stack 子进程栈空间的起始地址;
3> arg 传递给子进程的参数,需要和CLONE_SETTLS一起使用
4> ptid 存储父进程的pid,需要和CLONE_PARENT_SETTID一起使用
5> tls (Thread Local Storage) descriptor,需要和CLONE_SETTLS一起使用
6> ctid 存储子进程的pid,需要和CLONE_CHILD_SETTID选项一起使用
7> flag 创建进程的属性
返回值:
成功返回子进程的ID号,失败返回-1.
2 clone 3()属于一个调用clone()的超集,可以指定子堆栈区域大小。
clone_args 结构查看 man 3 clone。
关于异同点:

1> 退出信号:clone()在flags的低字节中指定,或在clone3中的cl_args.exit_signal
字段指定。如果该信号不是SIGCHLD
,那么父进程在使用wait(2)等待子进程退出时必须指定 __WALL 或WCLONE选项。如果没有指定任何信号(即0),则在子进程退出后不会向父进程发送任何信号。
2> set_tid & set_tid_size:
默认,内核会选择每个PID命名空间中的父进程的下一个PID号作为子进程的PID。当使用clone3()
创建进程时,可以使用set_tid
数组来为某些或所有PID命名空间中的进程指定PID。如果仅需要为当前PID命名空间中或新创建的PID命名空间中新创建的进程设置进程PID(flags
包含CLONE_NEWPID
),则set_tid
数组的第一个元素必须为期望的PID,且set_tid_size
必须为1(即此时仅有一个进程需要设置PID)。
如果希望给多个PID命名空间中新创建的进程设置一个特定的PID值,则set_tid
可以包含多个表项。第一个表项定义了最深层嵌套的PID命名空间中的PID,后续的表项包含在相应的祖先PID名称空间中的PID。set_tid_size
定义了PID命名空间的数目,且不能大于当前嵌套的PID命名空间的数目。
例子:这程序网上的,不知道原作者是谁了,能编译就行。
#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
#include <linux/sched.h>
#include <signal.h>
#include <sys/types.h>
#include <unistd.h>
#define FIBER_STACK 8192
int a;
void *stack;
int do_something() {
printf("This is the son, and my pid is:%d, and a = %d\n", getpid(), ++a);
free(stack);
exit(1);
}
int main() {
void * stack;
a = 1;
stack = malloc(FIBER_STACK);
if(!stack) {
printf("The stack failed\n");
exit(0);
}
printf("Creating son thread!!!\n");
clone(&do_something, (char *)stack + FIBER_STACK, CLONE_VM|CLONE_VFORK, 0);
printf("This is the father, and my pid is: %d, and a = %d\n", getpid(), a);
exit(1);
}
3 函数调用
