Gab*_*ern 4 linux pthreads system-calls
问题的简短版本:clone如果我想为我正在创建的线程分配一个新的TLS区域,我需要将什么参数传递给x86_64 Linux系统上的系统调用.
长版:
我正在研究一个研究项目和我正在尝试的东西我想使用clone系统调用而不是使用来创建线程pthread_create.但是,我也希望能够使用线程本地存储.我现在不打算创建多个线程,所以我可以为我使用克隆系统调用创建的每个线程创建一个新的TLS区域.
我正在查看手册页clone,它有关于TLS参数标志的以下信息:
CLONE_SETTLS (since Linux 2.5.32)
The newtls argument is the new TLS (Thread Local Storage) descriptor.
(See set_thread_area(2).)
Run Code Online (Sandbox Code Playgroud)
所以我查看了手册页,set_thread_area并注意到以下内容看起来很有希望:
When set_thread_area() is passed an entry_number of -1, it uses a
free TLS entry. If set_thread_area() finds a free TLS entry, the value of
u_info->entry_number is set upon return to show which entry was changed.
Run Code Online (Sandbox Code Playgroud)
但是,在尝试了一些之后,似乎set_thread_area在我的系统中没有实现(在x86_64平台上的Ubunut 10.04).当我运行以下代码时,我收到一条错误消息:set_thread_area() failed: Function not implemented
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <errno.h>
#include <sys/syscall.h>
#include <sys/types.h>
#include <linux/unistd.h>
#include <asm/ldt.h>
int main()
{
struct user_desc u_info;
u_info.entry_number = -1;
int rc = syscall(SYS_set_thread_area,&u_info);
if(rc < 0) {
perror("set_thread_area() failed");
exit(-1);
}
printf("entry_number is %d",u_info.entry_number);
}
Run Code Online (Sandbox Code Playgroud)
我也看到当我使用strace时,看看pthread_create调用时会发生什么,我看不到任何调用set_thread_area.我一直在查看nptl pthread源代码,试图了解它们在创建线程时所做的工作.但我还没有完全理解它,我认为它比我正在尝试做的更复杂,因为我不需要在pthread实现中具有强大功能的东西.我假设set_thread_area系统调用是针对x86的,并且有一种不同的机制用于x86_64.但目前我还没弄清楚它是什么,所以我希望这个问题可以帮助我了解一些我需要了解的内容.
我正在研究一个研究项目和我正在尝试的东西我想使用克隆系统调用而不是使用pthread_create来创建线程
在极不可能的情况下,你的新线程永远不会调用任何libc函数(或直接调用其他调用libc的东西;这也包括通过PLT的动态符号解析),那么你可以传递你想要的任何TLS存储作为new_tls参数为clone.
您应该忽略所有引用set_thread_area- 它们仅适用于32位/ ix86情况.
如果您正在计划在您的新创建的线程使用的libc,你应该放弃你的方法:libc 预计 TLS要建立一定的方式,有没有办法,因为当你打电话给你这样的设置安排clone直接.当发现您没有正确设置TLS 时,您的新线程将间歇性地崩溃libc.调试此类崩溃非常困难,唯一可靠的解决方案是......使用pthread_create.