Liunx下clone函数分析(二)
动机
这一篇继续探究clone函数,部分不同参数的运行情况。
clone
参数:
int clone(int (*fn)(void *fnarg), void *child_stack, int flags, void *arg, ...
/* pid_t *pid, struct user_desc *tls, pid_t *ctid */ );
fn是指向子进程执行时调用的函数,fnarg是可以传给该函数的参数,child_stack是为子进程分配的堆栈指针,arg是传给子进程的参数一般为0.
下面是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线程标准,子进程与父进程共享相同的线程群
原文链接:https://blog.csdn.net/gogokongyin/article/details/51178257
clone31-1Test.c
#define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
#include <sched.h>
#include <signal.h>
#include <sys/types.h>
#include <unistd.h>
#define FIBER_STACK 8192
#define CLONE_NUM 5
int a;
void * stacks[CLONE_NUM];
int myParams0 = 0 ;
int myParams1 = 1 ;
int myParams2 = 2 ;
int myParams3 = 3 ;
int myParams4 = 4 ;
int do_something(void *lparam)
{
int i;
int j;
i = (int)lparam;
//int a=0;
for (j=0;j<10000;j++)
++a;
printf("This is son, the pid is:%d, the param is: %d, the a is: %d\n", getpid(), i , a);
//free(stacks[i]); //这里我也不清楚,如果这里不释放,不知道子线程死亡后,该内存是否会释放,知情者可以告诉下,谢谢
exit(1);
}
int do_loop_time()
{
int i,j,k;
for (i=0;i<1000;i++)
for (j=0;j<1000;j++)
for (k=0;k<1000;k++)
;
}
int cloneMethod1()
{
clone(&do_something, (char *)(stacks[myParams0]) + FIBER_STACK, CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND, (void *)myParams0);//创建子线程
clone(&do_something, (char *)(stacks[myParams1]) + FIBER_STACK, CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND, (void *)myParams1);//创建子线程
// clone(&do_something, (char *)(stacks[myParams2]) + FIBER_STACK, CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND, (void *)myParams2);//创建子线程
// clone(&do_something, (char *)(stacks[myParams3]) + FIBER_STACK, CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND, (void *)myParams3);//创建子线程
// clone(&do_something, (char *)(stacks[myParams4]) + FIBER_STACK, CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND, (void *)myParams4);//创建子线程
}
int cloneMethod2()
{
int i;
for (i=0;i<CLONE_NUM;i++)
{
clone(&do_something, (char *)(stacks[i]) + FIBER_STACK, CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND, (void *)i);//创建子线程
}
}
int cloneMethod3()
{
int i;
pid_t parentPID = getpid();
pid_t myPID;
for (i=0;i<CLONE_NUM;i++)
{
myPID = getpid();
if (myPID == parentPID)
clone(&do_something, (char *)(stacks[i]) + FIBER_STACK, CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND, (void *)i);//创建子线程
}
}
int main()
{
int i;
a =0;
for (i=0;i<CLONE_NUM;i++)
{
stacks[i] = malloc(FIBER_STACK);//为子进程申请系统堆栈
if(!stacks[i])
{
printf("The stack failed\n");
exit(0);
}
}
printf("creating son thread!!!\n");
cloneMethod1();
char ch;
scanf("%c",&ch);
printf("This is father, my pid is: %d, the a is: %d\n", getpid(), a);
for (i=0;i<CLONE_NUM;i++)
{
// free(stacks[i]) ;
}
exit(1);
}
输出
[tj@tj bin]$ ./clone31-1Test
creating son thread!!!
This is son, the pid is:15539, the param is: 0, the a is: 10000
This is son, the pid is:15540, the param is: 1, the a is: 16321
1
This is father, my pid is: 15538, the a is: 16321
[tj@tj bin]$ ./clone31-1Test
creating son thread!!!
This is son, the pid is:15568, the param is: 0, the a is: 10302
This is son, the pid is:15569, the param is: 1, the a is: 13520
1
This is father, my pid is: 15567, the a is: 13520
[tj@tj bin]$ ./clone31-1Test
creating son thread!!!
This is son, the pid is:15572, the param is: 1, the a is: 13604
This is son, the pid is:15571, the param is: 0, the a is: 11317
1
This is father, my pid is: 15570, the a is: 13604
结果分析
此示例运行了三次,由二和第三个可以看出clone的2个子线程是并行的。第一个是偶发原因,至少是第一个子线程运行完了for循环,第二个子线程才进入for循环。
clone31-2Test.c
#define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
#include <sched.h>
#include <signal.h>
#include <sys/types.h>
#include <unistd.h>
#define FIBER_STACK 8192
#define CLONE_NUM 5
int a;
void * stacks[CLONE_NUM];
int myParams0 = 0 ;
int myParams1 = 1 ;
int myParams2 = 2 ;
int myParams3 = 3 ;
int myParams4 = 4 ;
int do_something(void *lparam)
{
int i;
int j;
i = (int)lparam;
//int a=0;
for (j=0;j<10000;j++)
printf("This is son, the pid is:%d, the param is: %d, the a is: %d\n", getpid(), i , ++a);
printf("This is son, the pid is:%d, the param is: %d, the a is: %d\n", getpid(), i , a);
//free(stacks[i]); //这里我也不清楚,如果这里不释放,不知道子线程死亡后,该内存是否会释放,知情者可以告诉下,谢谢
exit(1);
}
int do_loop_time()
{
int i,j,k;
for (i=0;i<1000;i++)
for (j=0;j<1000;j++)
for (k=0;k<1000;k++)
;
}
int cloneMethod1()
{
clone(&do_something, (char *)(stacks[myParams0]) + FIBER_STACK, CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND, (void *)myParams0);//创建子线程
clone(&do_something, (char *)(stacks[myParams1]) + FIBER_STACK, CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND, (void *)myParams1);//创建子线程
// clone(&do_something, (char *)(stacks[myParams2]) + FIBER_STACK, CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND, (void *)myParams2);//创建子线程
// clone(&do_something, (char *)(stacks[myParams3]) + FIBER_STACK, CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND, (void *)myParams3);//创建子线程
// clone(&do_something, (char *)(stacks[myParams4]) + FIBER_STACK, CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND, (void *)myParams4);//创建子线程
}
int cloneMethod2()
{
int i;
for (i=0;i<CLONE_NUM;i++)
{
clone(&do_something, (char *)(stacks[i]) + FIBER_STACK, CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND, (void *)i);//创建子线程
}
}
int cloneMethod3()
{
int i;
pid_t parentPID = getpid();
pid_t myPID;
for (i=0;i<CLONE_NUM;i++)
{
myPID = getpid();
if (myPID == parentPID)
clone(&do_something, (char *)(stacks[i]) + FIBER_STACK, CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND, (void *)i);//创建子线程
}
}
int main()
{
int i;
a =0;
for (i=0;i<CLONE_NUM;i++)
{
stacks[i] = malloc(FIBER_STACK);//为子进程申请系统堆栈
if(!stacks[i])
{
printf("The stack failed\n");
exit(0);
}
}
printf("creating son thread!!!\n");
cloneMethod1();
char ch;
scanf("%c",&ch);
printf("This is father, my pid is: %d, the a is: %d\n", getpid(), a);
for (i=0;i<CLONE_NUM;i++)
{
// free(stacks[i]) ;
}
exit(1);
}
输出
...
...
This is son, the pid is:15747, the param is: 0, the a is: 19818
This is son, the pid is:15748, the param is: 1, the a is: 19819
This is son, the pid is:15747, the param is: 0, the a is: 19820
This is son, the pid is:15748, the param is: 1, the a is: 19821
This is son, the pid is:15747, the param is: 0, the a is: 19822
This is son, the pid is:15748, the param is: 1, the a is: 19823
This is son, the pid is:15747, the param is: 0, the a is: 19824
This is son, the pid is:15748, the param is: 1, the a is: 19825
This is son, the pid is:15747, the param is: 0, the a is: 19826
This is son, the pid is:15748, the param is: 1, the a is: 19827
This is son, the pid is:15747, the param is: 0, the a is: 19828
This is son, the pid is:15748, the param is: 1, the a is: 19829
This is son, the pid is:15747, the param is: 0, the a is: 19830
This is son, the pid is:15748, the param is: 1, the a is: 19831
This is son, the pid is:15747, the param is: 0, the a is: 19832
This is son, the pid is:15748, the param is: 1, the a is: 19833
This is son, the pid is:15747, the param is: 0, the a is: 19834
...
...
结果分析
本示例将子线程的每次累加打印出来,从结果上可以证明上一个示例的推测是正确的,子线程交替并行。
clone31-3Test.c
#define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
#include <sched.h>
#include <signal.h>
#include <sys/types.h>
#include <unistd.h>
#define FIBER_STACK 8192
#define CLONE_NUM 5
int a;
void * stacks[CLONE_NUM];
int myParams0 = 0 ;
int myParams1 = 1 ;
int myParams2 = 2 ;
int myParams3 = 3 ;
int myParams4 = 4 ;
int do_something(void *lparam)
{
int i;
int j;
i = (int)lparam;
//int a=0;
for (j=0;j<10000;j++)
++a;
printf("This is son, the pid is:%d, the param is: %d, the a is: %d\n", getpid(), i , a);
free(stacks[i]); //这里我也不清楚,如果这里不释放,不知道子线程死亡后,该内存是否会释放,知情者可以告诉下,谢谢
exit(1);
}
int do_loop_time()
{
int i,j,k;
for (i=0;i<1000;i++)
for (j=0;j<1000;j++)
for (k=0;k<1000;k++)
;
}
int cloneMethod1()
{
clone(&do_something, (char *)(stacks[myParams0]) + FIBER_STACK, CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND, (void *)myParams0);//创建子线程
clone(&do_something, (char *)(stacks[myParams1]) + FIBER_STACK, CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND, (void *)myParams1);//创建子线程
// clone(&do_something, (char *)(stacks[myParams2]) + FIBER_STACK, CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND, (void *)myParams2);//创建子线程
// clone(&do_something, (char *)(stacks[myParams3]) + FIBER_STACK, CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND, (void *)myParams3);//创建子线程
// clone(&do_something, (char *)(stacks[myParams4]) + FIBER_STACK, CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND, (void *)myParams4);//创建子线程
}
int cloneMethod2()
{
int i;
for (i=0;i<CLONE_NUM;i++)
{
clone(&do_something, (char *)(stacks[i]) + FIBER_STACK, CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND, (void *)i);//创建子线程
}
}
int cloneMethod3()
{
int i;
pid_t parentPID = getpid();
pid_t myPID;
for (i=0;i<CLONE_NUM;i++)
{
myPID = getpid();
if (myPID == parentPID)
clone(&do_something, (char *)(stacks[i]) + FIBER_STACK, CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND, (void *)i);//创建子线程
}
}
int main()
{
int i;
a =0;
for (i=0;i<CLONE_NUM;i++)
{
stacks[i] = malloc(FIBER_STACK);//为子进程申请系统堆栈
if(!stacks[i])
{
printf("The stack failed\n");
exit(0);
}
}
printf("creating son thread!!!\n");
cloneMethod1();
char ch;
scanf("%c",&ch);
printf("This is father, my pid is: %d, the a is: %d\n", getpid(), a);
for (i=0;i<CLONE_NUM;i++)
{
// free(stacks[i]) ;
}
exit(1);
}
输出
creating son thread!!!
This is son, the pid is:15891, the param is: 1, the a is: 10000
This is son, the pid is:15892, the param is: 0, the a is: 15067
1
This is father, my pid is: 15890, the a is: 15067
结果分析
本示例在子线程运行函数里添加了free及时释放分配的内存空间。按照内存分配的网络资料来看,一个C程序分配内存后如果不free,则会一直占用内存。但程序执行结束后没有free的内存,会随着程序结束free。
clone31-4Test.c
#define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
#include <sched.h>
#include <signal.h>
#include <sys/types.h>
#include <unistd.h>
#define FIBER_STACK 8192
#define CLONE_NUM 5
int a;
void * stacks[CLONE_NUM];
int myParams0 = 0 ;
int myParams1 = 1 ;
int myParams2 = 2 ;
int myParams3 = 3 ;
int myParams4 = 4 ;
int do_something(void *lparam)
{
int i;
int j;
i = (int)lparam;
//int a=0;
for (j=0;j<10000;j++)
printf("This is son, the pid is:%d, the param is: %d, the a is: %d\n", getpid(), i , ++a);
printf("This is son, the pid is:%d, the param is: %d, the a is: %d\n", getpid(), i , a);
free(stacks[i]); //这里我也不清楚,如果这里不释放,不知道子线程死亡后,该内存是否会释放,知情者可以告诉下,谢谢
exit(1);
}
int do_loop_time()
{
int i,j,k;
for (i=0;i<1000;i++)
for (j=0;j<1000;j++)
for (k=0;k<1000;k++)
;
}
int cloneMethod1()
{
clone(&do_something, (char *)(stacks[myParams0]) + FIBER_STACK, CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND, (void *)myParams0);//创建子线程
clone(&do_something, (char *)(stacks[myParams1]) + FIBER_STACK, CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND, (void *)myParams1);//创建子线程
// clone(&do_something, (char *)(stacks[myParams2]) + FIBER_STACK, CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND, (void *)myParams2);//创建子线程
// clone(&do_something, (char *)(stacks[myParams3]) + FIBER_STACK, CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND, (void *)myParams3);//创建子线程
// clone(&do_something, (char *)(stacks[myParams4]) + FIBER_STACK, CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND, (void *)myParams4);//创建子线程
}
int cloneMethod2()
{
int i;
for (i=0;i<CLONE_NUM;i++)
{
clone(&do_something, (char *)(stacks[i]) + FIBER_STACK, CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND, (void *)i);//创建子线程
}
}
int cloneMethod3()
{
int i;
pid_t parentPID = getpid();
pid_t myPID;
for (i=0;i<CLONE_NUM;i++)
{
myPID = getpid();
if (myPID == parentPID)
clone(&do_something, (char *)(stacks[i]) + FIBER_STACK, CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND, (void *)i);//创建子线程
}
}
int main()
{
int i;
a =0;
for (i=0;i<CLONE_NUM;i++)
{
stacks[i] = malloc(FIBER_STACK);//为子进程申请系统堆栈
if(!stacks[i])
{
printf("The stack failed\n");
exit(0);
}
}
printf("creating son thread!!!\n");
cloneMethod1();
char ch;
scanf("%c",&ch);
printf("This is father, my pid is: %d, the a is: %d\n", getpid(), a);
for (i=0;i<CLONE_NUM;i++)
{
// free(stacks[i]) ;
}
exit(1);
}
输出
与31-2Test类似
结果分析
与31-3Test操作相同,将分配的内存及时free。
clone32Test.c
#define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
#include <sched.h>
#include <signal.h>
#include <sys/types.h>
#include <unistd.h>
#define FIBER_STACK 8192
#define CLONE_NUM 5
int a;
void * stacks[CLONE_NUM];
int myParams0 = 0 ;
int myParams1 = 1 ;
int myParams2 = 2 ;
int myParams3 = 3 ;
int myParams4 = 4 ;
int do_something(void *lparam)
{
int i;
int j;
i = (int)lparam;
int a=0;
for (j=0;j<10000;j++)
++a;
printf("This is son, the pid is:%d, the param is: %d, the a is: %d\n", getpid(), i , a);
//free(stacks[i]); //这里我也不清楚,如果这里不释放,不知道子线程死亡后,该内存是否会释放,知情者可以告诉下,谢谢
exit(1);
}
int do_loop_time()
{
int i,j,k;
for (i=0;i<1000;i++)
for (j=0;j<1000;j++)
for (k=0;k<1000;k++)
;
}
int cloneMethod1()
{
clone(&do_something, (char *)(stacks[myParams0]) + FIBER_STACK, CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND, (void *)myParams0);//创建子线程
clone(&do_something, (char *)(stacks[myParams1]) + FIBER_STACK, CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND, (void *)myParams1);//创建子线程
clone(&do_something, (char *)(stacks[myParams2]) + FIBER_STACK, CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND, (void *)myParams2);//创建子线程
clone(&do_something, (char *)(stacks[myParams3]) + FIBER_STACK, CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND, (void *)myParams3);//创建子线程
clone(&do_something, (char *)(stacks[myParams4]) + FIBER_STACK, CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND, (void *)myParams4);//创建子线程
}
int cloneMethod2()
{
int i;
for (i=0;i<CLONE_NUM;i++)
{
clone(&do_something, (char *)(stacks[i]) + FIBER_STACK, CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND, (void *)i);//创建子线程
}
}
int cloneMethod3()
{
int i;
pid_t parentPID = getpid();
pid_t myPID;
for (i=0;i<CLONE_NUM;i++)
{
myPID = getpid();
if (myPID == parentPID)
clone(&do_something, (char *)(stacks[i]) + FIBER_STACK, CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND, (void *)i);//创建子线程
}
}
int main()
{
int i;
a =0;
for (i=0;i<CLONE_NUM;i++)
{
stacks[i] = malloc(FIBER_STACK);//为子进程申请系统堆栈
if(!stacks[i])
{
printf("The stack failed\n");
exit(0);
}
}
printf("creating son thread!!!\n");
cloneMethod1();
char ch;
scanf("%c",&ch);
printf("This is father, my pid is: %d, the a is: %d\n", getpid(), a);
for (i=0;i<CLONE_NUM;i++)
{
// free(stacks[i]) ;
}
exit(1);
}
输出
creating son thread!!!
This is son, the pid is:This is son, the pid is:22435, the param is: 0, the a is: 22436,This is son, the pid is:This is son, the pid is:22435, the param is: 0, the a is: 22436, the param is: 1, the a is: 10000
This is son, the pid is:22439, the param is: 4, the a is: 10000
This is son, the pid is:22438, the param is: 3, the a is: 10000
This is son, the pid is:22437, the param is: 2, the a is: 10000
1
This is father, my pid is: 22434, the a is: 0
结果分析
从输出上可以看出,因为dosomething里将a赋值为0,所以每个输出都是10000。输出也不是按照子线程创建顺序。子线程是分别执行的不同dosomething函数,并且交替并行。
clone33-1Test.c
#define _GNU_SOURCE
#include <sys/wait.h>
#include <sys/utsname.h>
#include <sched.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/mman.h>
#define STACK_SIZE (1024 * 1024)
#define CLONE_NUM 5
int a;
char * stacks[CLONE_NUM];
int myParams0 = 0 ;
int myParams1 = 1 ;
int myParams2 = 2 ;
int myParams3 = 3 ;
int myParams4 = 4 ;
int do_something(void *lparam)
{
int i;
int j;
i = (int)lparam;
//int a=0;
for (j=0;j<10000;j++)
++a;
printf("This is son, the pid is:%d, the param is: %d, the a is: %d\n", getpid(), i , a);
//free(stacks[i]); //这里我也不清楚,如果这里不释放,不知道子线程死亡后,该内存是否会释放,知情者可以告诉下,谢谢
exit(1);
}
int do_loop_time()
{
int i,j,k;
for (i=0;i<1000;i++)
for (j=0;j<1000;j++)
for (k=0;k<1000;k++)
;
}
int cloneMethod1()
{
clone(&do_something, (char *)(stacks[myParams0]) + STACK_SIZE, CLONE_NEWUTS | CLONE_SIGHAND, (void *)myParams0);//创建子线程
clone(&do_something, (char *)(stacks[myParams1]) + STACK_SIZE, CLONE_NEWUTS | CLONE_SIGHAND, (void *)myParams1);//创建子线程
// clone(&do_something, (char *)(stacks[myParams2]) + STACK_SIZE, CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND, (void *)myParams2);//创建子线程
// clone(&do_something, (char *)(stacks[myParams3]) + STACK_SIZE, CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND, (void *)myParams3);//创建子线程
// clone(&do_something, (char *)(stacks[myParams4]) + STACK_SIZE, CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND, (void *)myParams4);//创建子线程
}
int cloneMethod2()
{
int i;
for (i=0;i<CLONE_NUM;i++)
{
clone(&do_something, (char *)(stacks[i]) + STACK_SIZE, CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND, (void *)i);//创建子线程
}
}
int cloneMethod3()
{
int i;
pid_t parentPID = getpid();
pid_t myPID;
for (i=0;i<CLONE_NUM;i++)
{
myPID = getpid();
if (myPID == parentPID)
clone(&do_something, (char *)(stacks[i]) + STACK_SIZE, CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND, (void *)i);//创建子线程
}
}
int main()
{
int i;
a =0;
for (i=0;i<CLONE_NUM;i++)
{
stacks[i] = mmap(NULL, STACK_SIZE, PROT_READ | PROT_WRITE,
MAP_PRIVATE | MAP_ANONYMOUS | MAP_STACK, -1, 0); //为子进程申请系统堆栈
if(stacks[i] == MAP_FAILED)
{
printf(" mmap The stack failed\n");
exit(0);
}
}
printf("creating son thread!!!\n");
cloneMethod1();
char ch;
scanf("%c",&ch);
printf("This is father, my pid is: %d, the a is: %d\n", getpid(), a);
for (i=0;i<CLONE_NUM;i++)
{
// free(stacks[i]) ;
}
exit(1);
}
输出
creating son thread!!!
1
This is father, my pid is: 23024, the a is: 0
结果分析
clone的参数为CLONE_NEWUTS ,则在子项中所做的更改无法传播回父项。