1. 程式人生 > >執行緒的終止和私有資料

執行緒的終止和私有資料

linux下執行緒的終止有有兩種方式:

1.通過return從執行緒函式返回. 2.通過掉用 pthread_exit()使執行緒退出,pthread_exit在標頭檔案 pthread.h中申明. 函式原型:void pthread_exit(void * retval); 注意,有兩種特殊的情況,第一種情況是,在主執行緒中,如果從main函式返回 或是呼叫了exit()函式退出主執行緒,則整個程序都將終止,此時程序中所有的執行緒也將終止,因此在主執行緒中不能過早的從main函式中返回.另一種是如果主執行緒呼叫 pthread_exit()函式,僅僅是主執行緒消亡,程序不會結束. 執行緒終止最重要的問題是資源釋放的問題,特別是一些臨界資源,臨界資源在一段時間內只能被一個執行緒所持有,當其它執行緒要使用臨界資源時提出請求,如果該資源未被使用則申請成功,否則等待,linux下提供了一對函式pthread_cleanup_push(),pthread_cleaned_pop()用於自動釋放資源,兩個函式之間的終止執行緒的動作都將執行清理函式. 執行緒的等待函式pthread_join(pthread_t th,void *thread_return,)

#include <stdio.h>                                                                                                                              
#include <stdlib.h>
#include <pthread.h>
#include <unistd.h>
const char *message="yanglongfei";
void thread(void *arg)
{
        pthread_t newphid;
        newphid=pthread_self();
        printf("我是新執行緒,我的ID = %u,文章=%s\n",(unsigned)newphid,(char*)arg);
        sleep(3);
        pthread_exit(0);
}
int main()
{
        pthread_t thid;
        int status;
        pthread_create(&thid,NULL,(void *)&thread,(void*)message);
        pthread_join(thid,(void *)&status);
        printf("新執行緒的退出碼是:%d\n",status);
        pthread_exit(0);
}

結果:

[email protected]:~/syc/第八章$ ./pthreadgetset1
我是新執行緒,我的ID = 729642752,文章=yanglongfei
新執行緒的退出碼是:0

第一句輸出後,等待了三秒,才結束.

2.私有資料:

1.概念及作用:在單執行緒中,我們經常要用到"全域性變數"以實現多個函式間共享資料,在多執行緒的環境下,由於資料空間是共享的,因此全域性變數也為所有執行緒所共有。但有時應用程式設計中有必要提供執行緒私有的全域性變數,僅在某個執行緒中有效,但卻可以跨多個函式訪問,比如 程式可能需要每個執行緒維護一個連結串列,而使用相同的函式操作,最簡單的辦法就是使用同名而不同變數地址的執行緒相關資料結構。這樣的資料結構可以由Posix 執行緒庫維護,稱為執行緒私有資料(Thread-specific Data,或TSD)。 在分配執行緒私有資料之前,要建立與該資料相關聯的key. 2.int pthread_key_create(pthread_key_t *keyp,void(*destructor)(void *));  返回值:若成功返回0,否則返回錯誤編碼。 需要注意的是:建立的key存放在keyp指向的記憶體單元,所以為了方便最好把它定義為一個全域性變數。如果建立一個執行緒的私有資料,必須保證pthread_key_create對於每個pthread_key_t變數僅僅被呼叫一次,因為一個鍵入果被建立兩次,其實是在建立兩個不同的鍵,第二個鍵將覆蓋第一個鍵,第一個鍵以及任何執行緒為其關聯的執行緒私有資料將丟失. 2.關於解構函式void (*destructor)(void *); 當執行緒退出時,如果執行緒的私有資料地址被置為NULL,那麼解構函式就不會被呼叫.當執行緒呼叫pthread_exit或者執行緒執行返回,正常退出時,解構函式就會被呼叫,異常退出不會呼叫解構函式. 3.執行緒退出時,執行緒私有資料的解構函式將按照OS實現定義的順序被呼叫。解構函式可能呼叫另外一個函式,而該函式可能建立新的執行緒私有資料而且把這個線 程私有資料和當前的鍵關聯起來。當所有的解構函式都呼叫完成以後,系統會檢查是否有非NULL的執行緒私有資料值與鍵關聯,如果有的話,再次呼叫解構函式, 這個過程一直重複到執行緒所有的鍵都為NULL值執行緒私有資料,或者已經做了PTHREAD_DESTRUCTOR_ITERATIONS中定義的最大次數 的嘗試. TSD的讀寫都通過專門的Posix Thread函式進行,其API定義如下: int pthread_setspecific(pthread_key_t key, const void *pointer) void * pthread_getspecific(pthread_key_t key) 寫入(pthread_setspecific())時,將pointer的值(不是所指的內容)與key相關聯,而相應的讀出函式則將與key相關聯的資料讀出來。資料型別都設為void *,因此可以指向任何型別的資料。 在LinuxThreads中,使用了一個位於執行緒描述結構(_pthread_descr_struct)中的二維void *指標陣列來存放與key關聯的資料,陣列大小由以下幾個巨集來說明: #define PTHREAD_KEY_2NDLEVEL_SIZE 32 #define PTHREAD_KEY_1STLEVEL_SIZE ((PTHREAD_KEYS_MAX + PTHREAD_KEY_2NDLEVEL_SIZE - 1) / PTHREAD_KEY_2NDLEVEL_SIZE) 其中在/usr/include/bits/local_lim.h中定義了PTHREAD_KEYS_MAX為1024,因此一維陣列大小為32。而具體存放的位置由key值經過以下計算得到: idx1st = key / PTHREAD_KEY_2NDLEVEL_SIZE idx2nd = key % PTHREAD_KEY_2NDLEVEL_SIZE 也就是說,資料存放與一個32×32的稀疏矩陣中。同樣,訪問的時候也由key值經過類似計算得到資料所在位置索引,再取出其中內容返回。 6.int pthread_delete(pthread_key_t *keyp),注意呼叫pthread_delete不會啟用與鍵關聯的解構函式,容易造成記憶體洩露。 當刪除執行緒私有資料鍵的時候,不會影響任何執行緒對該鍵設定的執行緒私有資料值,甚至不影響呼叫執行緒當前鍵值,所以容易造成記憶體洩露,如果你不記得釋放所有執行緒內與該鍵相關聯的私有資料空間的話。 使用已經刪除的私有資料鍵將導致未定義的行為。 程式設計建議:最後不刪除執行緒私有資料鍵!!!尤其當一些執行緒仍然持有該鍵的值時,就更不該釋放該鍵!!!

相關推薦

執行終止私有資料

linux下執行緒的終止有有兩種方式: 1.通過return從執行緒函式返回. 2.通過掉用 pthread_exit()使執行緒退出,pthread_exit在標頭檔案 pthread.h中申明. 函式原型:void pthread_exit(void * retva

執行概述、執行控制執行私有資料

一、執行緒概述   在許多經典的作業系統教科書中,總是把程序定義為程式的執行例項,它並不執行什麼, 只是維護應用程式所需的各種資源,而執行緒則是真正的執行實體。在一個程序中的多個執行路線叫做執行緒。為了

Java多執行之interrupt()執行終止方式

1. interrupt()說明 在介紹終止執行緒的方式之前,有必要先對interrupt()進行了解。 關於interrupt(),java的djk文件描述如下:http://docs.oracle.com/javase/7/docs/api/ Interrupts this thread

泥瓦匠聊併發程式設計基礎篇:執行中斷終止

1 執行緒中斷 1.1 什麼是執行緒中斷? 執行緒中斷是執行緒的標誌位屬性。而不是真正終止執行緒,和執行緒的狀態無關。執行緒中斷過程表示一個執行中的執行緒,通過其他執行緒呼叫了該執行緒的 interrupt() 方法,使得該執行緒中斷標誌位屬性改變。 深入思考下,執行緒中斷不是去中斷了執行緒,

大量資料情況下單執行插入執行insert資料庫的效能測試

之前一直沒有遇到過大批量資料入庫的場景,所以一直沒有思考過在大量資料的情況下單執行緒插入和多執行緒插入的效能情況。今天在看一個專案原始碼的時候發現使用了多執行緒insert操作。 於是簡單的寫了一個測試程式來測試一批資料在N個執行緒下的insert情況。 public class ThreadImport

Python多執行執行建立終止

python主要是通過thread和threading這兩個模組來實現多執行緒支援。python的thread模組是比較底層的模組,python的threading模組是對thread做了一些封裝,可以更加方便的被使用。但是python(cpython)由於GIL的存在無法

學習筆記之執行、Thread類執行終止相關整理(下)——執行異常&JVM停止

提到執行緒的中斷在某些情況下會丟擲InterruptedException異常,最終導致執行緒的終止。其實,執行緒也有可能由於其他異常原因造成終止,在某些情況下為了做一些妥善的處理,我們需要捕獲這些異常情況。看下面程式碼,覺得會怎樣? 1 2 3 4 5

執行執行通訊,主執行用bundle傳送資料到子執行

package com.wangcan; import android.os.Bundle; import android.os.Handler; import android.os.HandlerThread; import android.os.Message; im

JAVA的interrupt()方法執行終止的方式

1 // Demo3.java的原始碼 2 class MyThread extends Thread { 3 4 private volatile boolean flag= true; 5 public void stopTask() { 6 flag =

Java 多執行基礎(十)interrupt()執行終止方式

Java 多執行緒基礎(十)interrupt()和執行緒終止方式 一、interrupt() 介紹 interrupt() 定義在 Thread 類中,作用是中斷本執行緒。 本執行緒中斷自己是被允許的;其它執行緒呼叫本執行緒的 interrupt() 方法時,會通過 checkAccess() 檢查許可權。

C# 應用 - 多執行 7) 處理同步資料之 Synchronized code regions (同步程式碼區域): Monitor lock

目錄: 1. System.Threading.Monitor:提供同步訪問物件的機制; 2. lock 是語法糖,是對 Monitor Enter 和 Exit 方法的一個封裝 3. lock 案例 ### 1. Monitor #### 1. 基本方法 1. public static void Ent

Java 多執行 joininterrupt 方法

簡述: 使用Java多執行緒中join和interrupt函式 《Java程式設計思想》 P669 ~ P670 一個執行緒可以再其他執行緒上呼叫join()方法,其效果是等待一段時間直到第二個執行緒結束才繼續執行。 如果某個執行緒在另一個執行緒t上呼叫t.join(), 此

Java執行-同步非同步的區別

1.                                         &nb

執行退出執行資源回收問題

最近專案中遇到迴圈8M的記憶體洩漏問題,排查後發現是由於特殊場景下使子執行緒異常退出,主執行緒發現子執行緒退出便再次建立執行緒,此時未回收退出執行緒的資源造成了記憶體洩漏,導致資料庫宿主機oom,此問題不僅導致記憶體洩漏,還會使執行緒控制代碼用完導致其他程序無法分配執行緒的風險。 下面來

Java執行學習總結(執行的概念)

執行緒的概念: 多執行緒允許在程式中併發執行多個指令流,每個指令流都稱為一個執行緒,彼此間互相獨立。它和程序一樣擁有獨立的執行控制,由作業系統負責排程,區別在於執行緒沒有獨立的儲存空間,而是和所屬程序中的其它執行緒共享一個儲存空間,這使得執行緒間的通訊遠較程序簡單。 具體到java記憶體模型,

JAVA多執行(三) 執行鎖的深度化

 github演示程式碼地址:https://github.com/showkawa/springBoot_2017/tree/master/spb-demo/src/main/java/com/kawa/thread 1.執行緒池  1.1 執行緒池是什麼 Java中的執行緒

PYTHON——多執行:佇列Queue資料結構

1、佇列模組簡介   佇列是一種資料結構,用於存放資料,類似列表。它是先進先出模式(FIFO模式),類似管道一般; 單執行緒不需要用到佇列Queue,它主要用在多執行緒之間的,Queue稱為多執行緒利器。 列表在多執行緒共享資源的話,與queue佇列比較,主要表現為列表在多執行緒中,資料不安全。多個執行

執行讀寫佇列資料

MFC對話方塊中一個按鈕的響應函式實現兩個功能: 顯示資料同時處理資料,因此開兩個執行緒,一個執行緒顯示資料(開了一個定時器,響應WM_TIMER訊息按照一定時間間隔向TeeChart圖表新增資料並顯示)同時在佇列隊尾新增資料,另一個執行緒從該佇列隊頭去資料來處理。 下面就來解決這個案例。先來分

執行案例產生的資料誤差

xl_echo編輯整理,歡迎轉載,轉載請宣告文章來源。更多IT、程式設計案例、資料請聯絡QQ:1280023003 百戰不敗,依不自稱常勝,百敗不頹,依能奮力前行。——這才是真正的堪稱強大!! 需求:一個電影院售票站,總共有四個視窗,但是隻有50張票,如何保證四個視窗售票的

高併發程式設計:執行安全ThreadLocal

執行緒安全的概念:當多個執行緒訪問某一個類(物件或方法)時,這個類始終都能表現出正確的行為,那麼這個類(物件或方法)就是執行緒安全的。 執行緒安全 說的可能比較抽象,下面就以一個簡單的例子來看看什麼是執行緒安全問題。 public class MyThread impleme