如何给clone()分配合适的Stack_Size

我尝试用 clone-execl 替代 system()
但是怎么给 clone() 分配一个合适的 Stack_Size 而不是分配一个过大的内存?
下面是代码

    static int Child(void *arg){
        execl("/bin/ls", "ls", "-alh", "--color=auto", "NULL");
        return 0;
    }
    char run_program(void){
        int STACK_SIZE = 10000;
        void *Child_Stack = calloc(STACK_SIZE, sizeof(char));
        if (Child_Stack == NULL){
            return 'X';
        }
        if (clone(Child, Child_Stack + STACK_SIZE, CLONE_VFORK, NULL) == -1){
            free(Child_Stack);
            return 'X';
        }
        return 'V';
    }

另外,return 'V'; 上面有没有必要加上 free(Child_Stack)?
先多谢各位了

阅读 4.4k
3 个回答

你这个并不需要分配多大的栈,因为在execl后,子线程就完全独立了,并不会和父进程共享内存空间,和fork没什么区别,我测试时只需要大概1200个字节就可以了。
因为execl后那段分配的栈空间就没有用处了,所以free掉比较好。

参考 stackoverflow

@fplust 刚起床又测试了一次,发现clone需要的stack_size是clone调用的函数所需要的内存大小,低于就会execl失败。
比如
在上面的代码中的Child函数里加上 char ABC[10];
Stack_Size就要增加16字节才能成功执行execl
另外,如果在char ABC[10];上面加上printf之类的就算execl失败也会成功输出

感觉像我这样一个个字节的给他增加有点傻。。。再等等看你们有什么方法

int stacktop;
....

int stackdown;
stacksize = &stacktop - &stackdown;
execl(...);

clone(Child, Child_Stack + stacksize + PADDING ....)

利用以下几点:
1.栈是向下增加。所以可以用两个变量找出这个位置。
2.execl不会返回,它不需要栈来保存返回值,只需要保存栈顶位置就可以。
3.PADDING是一次函数调用的栈开销,这是一个固定值。

缺点:
1.第一次,stacksize需要足够大。
2.child中不调用其它函数,如果需要调用其它函数,需要考虑最深的函数要用多少栈。

另外也可以通过向栈填特殊标志的方式找到最深的栈位置。

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题