91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

基于linuxthreads-2.0.1如何分析線程的棧

發布時間:2021-12-09 09:33:04 來源:億速云 閱讀:136 作者:柒染 欄目:大數據

本篇文章為大家展示了基于linuxthreads-2.0.1如何分析線程的棧,內容簡明扼要并且容易理解,絕對能使你眼前一亮,通過這篇文章的詳細介紹希望你能有所收獲。

線程本質上是進程中的一個執行流,我們知道,進程有代碼段,線程其實就是進程代碼段中的其中一段代碼。線程的一種實現是作為進程來實現的。通過調用clone,新建一個進程,然后執行父進程代碼段里的一個代碼片段。文件、內存等信息都是共享的。因為內存是共享的,所以線程不能共享棧,否則訪問棧的地址的時候,會映射到相同的物理地址,那樣就會互相影響,所以每個線程會有自己獨立的棧。在調用clone函數的時候會設置棧的范圍。下面通過linuxthreads的代碼看看線程的棧。linuxthreads里有一個__pthread_initialize函數,該函數會在main函數執行前執行。在該函數中會設置主線程的棧范圍。

   
     
 
    
    

// CURRENT_STACK_FRAME 即sp寄存器。按STACK_SIZE大小對齊
__pthread_initial_thread_bos = (char *)(((long)CURRENT_STACK_FRAME - 2 * STACK_SIZE) & ~(STACK_SIZE - 1));              

__pthread_initial_thread_bos 保存主線程的棧頂位置。

然后當我們第一次調用pthread_create創建線程的時候,會調用pthread_initialize_manager函數初始化manager線程。manager線程是管理其他的線程的線程。

   
     
 
    
    

// 在堆上分配一塊內存用于manager線程的棧,棧頂
 __pthread_manager_thread_bos = malloc(THREAD_MANAGER_STACK_SIZE);
// 高地址是棧底
 __pthread_manager_thread_tos = __pthread_manager_thread_bos + THREAD_MANAGER_STACK_SIZE;              

然后調用clone函數設置manager線程的棧。

   
     
 
    
    __clone(__pthread_manager,__pthread_manager_thread_tos, CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND, (void *)(long)manager_pipe[0]);

最后在函數pthread_handle_create中設置創建的線程的棧,pthread_handle_create函數是調用pthread_create函數的時候被調用的函數。

   
     
 
    
    

// THREAD_STACK_START_ADDRESS 即__pthread_initial_thread_bos,即主線程的棧頂
#ifndef THREAD_STACK_START_ADDRESS
#define THREAD_STACK_START_ADDRESS  __pthread_initial_thread_bos
#endif
#define THREAD_SEG(seg) ((pthread_t)(THREAD_STACK_START_ADDRESS - (seg) * STACK_SIZE) - 1)
#define SEG_THREAD(thr) (((size_t)THREAD_STACK_START_ADDRESS - (size_t)(thr+1)) / STACK_SIZE)
pthread_t new_thread = THREAD_SEG(sseg);
mmap((caddr_t)((char *)(new_thread+1) - INITIAL_STACK_SIZE),INITIAL_STACK_SIZE, PROT_READ | PROT_WRITE | PROT_EXEC,MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED | MAP_GROWSDOWN, -1, 0);              

從上面代碼可知,新建的線程的棧在主線程的棧頂下面(即地址小于主線程的棧頂),創建線程的時候,首先計算新線程的棧地址,然后調用mmap劃出這塊地址。否則訪問的時候會segmentfault。最后調用clone創建進程(線程)并設置棧的棧頂和棧底位置。

   
     
 
    
     __clone(pthread_start_thread, new_thread,(CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND| PTHREAD_SIG_RESTART),new_thread);

內存布局如下。

基于linuxthreads-2.0.1如何分析線程的棧

從上面的棧分布我們還可以知道一個信息,即當前執行的代碼屬于哪個線程。

   
     
 
    
    

static inline pthread_t thread_self (void)
{
#ifdef THREAD_SELF
 THREAD_SELF
#else
 char *sp = CURRENT_STACK_FRAME;
 // 大于初始化棧則是主線程
 if (sp >= __pthread_initial_thread_bos)
   return &__pthread_initial_thread;
 // 這是manager線程自己申請的空間
 else if (sp >= __pthread_manager_thread_bos
  && sp < __pthread_manager_thread_tos)
   return &__pthread_manager_thread;
 else
   // sp肯定落在某個線程的棧范圍內,STACK_SIZE-1使得低n位全1, 或sp再加1即往高地址,按STACK_SIZE對齊,減去一個pthread_t得到tcb
   return (pthread_t) (((unsigned long int) sp | (STACK_SIZE - 1)) + 1) - 1;
#endif
}              

這就是linuxthreads獲取當前線程的是方法。

上述內容就是基于linuxthreads-2.0.1如何分析線程的棧,你們學到知識或技能了嗎?如果還想學到更多技能或者豐富自己的知識儲備,歡迎關注億速云行業資訊頻道。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

鲁甸县| 法库县| 大邑县| 来凤县| 廉江市| 江陵县| 葫芦岛市| 尼勒克县| 南部县| 马鞍山市| 阿城市| 鹤山市| 九台市| 永顺县| 禄丰县| 崇文区| 郎溪县| 蒙山县| 水富县| 耿马| 四子王旗| 电白县| 宣恩县| 桦甸市| 静乐县| 霸州市| 托克逊县| 都江堰市| 晴隆县| 阳信县| 凤城市| 酉阳| 封开县| 永康市| 论坛| 北碚区| 双鸭山市| 乐亭县| 沙坪坝区| 怀来县| 通州市|