Linux學習--執行緒控制

Li_Ning_發表於2016-08-09

關於執行緒控制,主要就是幾個模組,我們一個一個消滅、消化:

一、執行緒建立:

1.先來看看在Linux環境下的執行緒建立函式:


分析:意思很明顯:

1.函式名是 pthread_create  ;

2.功能:就是建立一個執行緒;

3.函式原型:

#include <pthread.h>  //標頭檔案

int pthread_create(pthread_t *thread, const pthread_attr_t *attr,void *(*start_routine) (void *), void *arg);
4.返回值:

成功返回0,失敗返回錯誤號。以前學過的系統函式都是成功返回0,失敗返回-1,而錯誤 號儲存在全域性變數errno中,而pthread庫的函式都是通過返回值返回錯誤號;

雖然每個執行緒也都有一個errno,但這是為了相容其它函式介面而提供的,pthread庫本身並不使用它,通過返回值返回錯誤碼更加清晰。

5.引數:第一個是執行緒id;第二個是 執行緒屬性(結合、分離、大小、執行時棧等);第三個是新執行緒的處理函式;第四個表示新執行緒處理函式的引數;

如下:


執行結果:


2、關於執行緒:

       在一個執行緒中呼叫pthread_create()建立新的執行緒後,當前執行緒從pthread_create()返回繼續往下執行,而新的執行緒所執行的程式碼由我們傳給pthread_create的函式指標

start_routine決 定。 start_routine函式接收一個引數,是通過pthread_create的arg引數傳遞給它的,該引數的型別為 void *,這個指標按什麼型別解釋由呼叫者自己定義。

start_routine的返回值型別也是void *,這指標的含義同樣由呼叫者自己定義。start_routine返回時,這個執行緒就退出了,其它執行緒 可以呼叫pthread_join得到start_routine的返回值,

類似於父程式呼叫wait(2)得到子程式的退出 狀態。

       pthread_create成功返回後,新建立的執行緒的id被填寫到thread引數所指向的記憶體單元。我們知道程式id的型別是pid_t,每個程式的id在整個系統中是唯一的,

呼叫getpid(2)可以獲得當前程式的id,是一個正整數值。執行緒id的型別是thread_t,它只在當前程式中保證是唯一的,在不同的系 統中thread_t這個型別有不同的實現,

它可能是一個整數值,也可能是一個結構體,也可能是一個地址,所以不能簡單地當成整數用printf列印,呼叫pthread_self(3)可以獲得當前執行緒的id。  attr參數列示執行緒屬性,

所有程式碼例子都傳NULL給attr引數,表示執行緒屬性取預設值。可知在Linux上,pthread_t型別是一個地址值,屬於同一程式的多個執行緒呼叫getpid(2)可以得到相同的程式號,

而呼叫pthread_self(3)得到的執行緒號各不相同。  

       由於pthread_create的錯誤碼不儲存在errno中,因此不能直接用perror(3)列印錯誤資訊,可以先 用strerror(3)把錯誤碼轉換成錯誤資訊再列印。 

二、執行緒終止:

如果需要只終止某個執行緒而不終止整個程式,可以有三種方法: 

 1. 從執行緒函式return:這種方法對主執行緒不適用,從main函式return相當於呼叫exit。 

分析:這個很明白,就不多說,main函式中return也相當,exit();即終止程式;

 2. 一個執行緒可以呼叫pthread_cancel終止同一程式中的另一個執行緒。 

函式標頭檔案、函式原型:


返回值:


例子:


3. 執行緒可以呼叫pthread_exit終止自己。 

函式原型、標頭檔案、返回值:



retval是void *型別,和執行緒函式返回值的用法一樣,其它執行緒可以呼叫pthread_join獲得這個指 針。 

需要注意,pthread_exit或者return返回的指標所指向的記憶體單元必須是全域性的或者是用 malloc分配的;

不能線上程函式的棧上分配,因為當其它執行緒得到這個返回指標時執行緒函式已 經退出了。 

三、執行緒等待:

標頭檔案、函式原型:


呼叫該函式的執行緒將掛起等待,直到id為thread的執行緒終止。thread執行緒以不同的方法終止,通過pthread_join得到的終止狀態是不同的,總結如下:

1. 如果thread執行緒通過return返回,value_ptr所指向的單元裡存放的是thread執行緒函式的返回值。  

2. 如果thread執行緒被別的執行緒呼叫pthread_cancel異常終掉,value_ptr所指向的單元裡存放的是常數PTHREAD_CANCELED。 

3. 如果thread執行緒是自己呼叫pthread_exit終止的,value_ptr所指向的單元存放的是傳給 pthread_exit的引數。 

如果對thread執行緒的終止狀態不感興趣,可以傳NULL給value_ptr 引數。  

返回值:成功返回零,失敗返回錯誤號:


程式碼:


以下為上邊三種執行緒控制的完整測試程式碼:

#include<stdlib.h>
#include<stdlib.h>
#include<pthread.h>

void *thread_run(void *str)
{
    printf("%s\n",(char*)str);
    printf("次執行緒正在運作,請稍後...\n");
    sleep(5);
    printf("次執行緒運作結束..\n");
    pthread_exit((void*)2); 
}

int main()
{
    pthread_t id;
    int ret = pthread_create(&id,NULL,thread_run,"建立了一個執行緒...");
    if(ret !=  0)
    {
	printf("建立執行緒錯誤...\n");
	return ret;
    }

    //sleep(6);
    pthread_cancel(id);   //取消執行緒
    int re = 0;
   // sleep(1);

    if(0 == pthread_join(id,NULL)) //等待 id這個執行緒結束,等待成功返回零,失敗返回錯誤號
    {
	printf("執行緒等待成功...,並且資源回收完成...(執行緒合併)\n");
	re = 0;
    }

    else
    {
	printf("執行緒等待失敗...\n");
	re = 1;
    }

    return re;
}
賜教!

相關文章