Liunx下clone函数分析第二篇

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 ,则在子项中所做的更改无法传播回父项。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值