如何在Linux上将CLONE_SETTLS与CLONE_VM结合使用

问题描述

|| 我曾遇到过这样一种情况:在两个处理器之间对glibc / syscall的多次调用(其中一个是通过使用CLONE_VM调用clone()创建的)最终将导致我的程序崩溃。 根据我的理解,如果我打算使用CLONE_VM t,则还必须指定CLONE_SETTLS。 谁能给我一个例子,说明如何为我的新克隆准备TLS存储以及如何使用CLONE_SETTLS实际执行clone()调用吗?     

解决方法

        下面加上一粒盐,因为我只看了“编译过程中”(这里没有木剑)。 Glibc / NPTL使用TLS来存储很多线程状态。 TLS指向每个线程“ 0”(“ 1”可能表示pthread描述符),该线程在“ 2”处的线程本地堆栈中分配,从“ 3”调用。 在x86中,
struct pthread
的第一个成员是ѭ5should,它应指向
struct user_desc
(其条目号可能在体系结构之间以及内核版本之间有所不同,我系统上的glibc使用6作为其内部TLS)。
tcb
作为自变量传递给
do_clone()
。 如果仔细查看这些功能,您会发现glibc在TLS上存储了很多信息:有关线程本地堆栈的信息,该程序是否有多个线程,健壮的互斥锁列表,线程启动例程及其参数,pthread属性标志,排程政策... 总而言之,如果您可以摆脱真正的pthread线程的困扰,它将更加简单。     ,        另一种方法是先呼叫
clone
,然后呼叫
pthread_create
。 通过这种方式,您正在使用线程库来获取正确的TLS(位于线程堆栈上)。 示例代码:
int tmp_run(void *arg) {
    void *ret;
    pthread_t thread;
    // now call the wanted function
    pthread_create(&thread,NULL,run,arg);
    pthread_join(thread,&ret);
    return (long) ret;
}

int main(...) {
   ...
   int clone_pid = clone (tmp_run,stack,flags arg);
   ...
}
如果需要对线程属性进行更多控制(例如,堆栈位置),请查看pthread_create。