Linux--進(jìn)程(clone)
1 clone:產(chǎn)生線程,可以對(duì)父子進(jìn)程間的共享、復(fù)制進(jìn)行精確控制。也可以允許新創(chuàng)建的進(jìn)程共享調(diào)用它的進(jìn)程(通常是父進(jìn)程)的部分資源,比如內(nèi)存空間、文件描述符表、信號(hào)量等,具體需要共享那些內(nèi)容可以通過clone的flag參數(shù)設(shè)置。
man clone

用于創(chuàng)建一個(gè)新的子進(jìn)程,類似fork(2)。與fork(2)相比,它可以更精確地控制調(diào)用進(jìn)程和子進(jìn)程之間的執(zhí)行上下文細(xì)節(jié)。
1> fn 新創(chuàng)建進(jìn)程的入口函數(shù);
2> stack 子進(jìn)程棧空間的起始地址;
3> arg 傳遞給子進(jìn)程的參數(shù),需要和CLONE_SETTLS一起使用
4> ptid 存儲(chǔ)父進(jìn)程的pid,需要和CLONE_PARENT_SETTID一起使用
5> tls (Thread Local Storage) descriptor,需要和CLONE_SETTLS一起使用
6> ctid 存儲(chǔ)子進(jìn)程的pid,需要和CLONE_CHILD_SETTID選項(xiàng)一起使用
7> flag 創(chuàng)建進(jìn)程的屬性
返回值:
成功返回子進(jìn)程的ID號(hào),失敗返回-1.
2 clone 3()屬于一個(gè)調(diào)用clone()的超集,可以指定子堆棧區(qū)域大小。
clone_args 結(jié)構(gòu)查看 man 3 clone。
關(guān)于異同點(diǎn):

1> 退出信號(hào):clone()在flags的低字節(jié)中指定,或在clone3中的cl_args.exit_signal
字段指定。如果該信號(hào)不是SIGCHLD
,那么父進(jìn)程在使用wait(2)等待子進(jìn)程退出時(shí)必須指定 __WALL 或WCLONE選項(xiàng)。如果沒有指定任何信號(hào)(即0),則在子進(jìn)程退出后不會(huì)向父進(jìn)程發(fā)送任何信號(hào)。
2> set_tid & set_tid_size:
默認(rèn),內(nèi)核會(huì)選擇每個(gè)PID命名空間中的父進(jìn)程的下一個(gè)PID號(hào)作為子進(jìn)程的PID。當(dāng)使用clone3()
創(chuàng)建進(jìn)程時(shí),可以使用set_tid
數(shù)組來(lái)為某些或所有PID命名空間中的進(jìn)程指定PID。如果僅需要為當(dāng)前PID命名空間中或新創(chuàng)建的PID命名空間中新創(chuàng)建的進(jìn)程設(shè)置進(jìn)程PID(flags
包含CLONE_NEWPID
),則set_tid
數(shù)組的第一個(gè)元素必須為期望的PID,且set_tid_size
必須為1(即此時(shí)僅有一個(gè)進(jìn)程需要設(shè)置PID)。
如果希望給多個(gè)PID命名空間中新創(chuàng)建的進(jìn)程設(shè)置一個(gè)特定的PID值,則set_tid
可以包含多個(gè)表項(xiàng)。第一個(gè)表項(xiàng)定義了最深層嵌套的PID命名空間中的PID,后續(xù)的表項(xiàng)包含在相應(yīng)的祖先PID名稱空間中的PID。set_tid_size
定義了PID命名空間的數(shù)目,且不能大于當(dāng)前嵌套的PID命名空間的數(shù)目。
例子:這程序網(wǎng)上的,不知道原作者是誰(shuí)了,能編譯就行。
#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 函數(shù)調(diào)用
