1. 程式人生 > 其它 >基於執行緒的併發程式設計(一):初識執行緒程式設計

基於執行緒的併發程式設計(一):初識執行緒程式設計

導航

什麼是執行緒

執行緒就是執行在程序上下文中的單元。程序是由多個執行緒組成,最簡單的程序由一個執行緒組成,而這個執行緒就叫做主執行緒。執行緒由核心自動排程。每個執行緒都有自己的執行緒上下文,包括一個唯一的執行緒ID棧指標程式計數器通用目的暫存器條件碼
由於多執行緒程式設計均在同一程序中,所以執行緒之間共享這個程序虛擬地址空間的所有內容,包括它的程式碼、資料、堆、共享庫和開啟檔案等。這也是的執行緒的併發程式設計的引發安全性問題的原因,後續會對執行緒安全進行展開闡述。
在這裡插入圖片描述如上圖所示,程序開始生命週期時都是單一執行緒,而這個執行緒稱為主執行緒

。在某一個時刻,主執行緒建立一個對等執行緒,從這個時刻開始,兩個執行緒就併發的執行。主執行緒執行延遲呼叫時,如read或者sleep操作,或者因為被核心的定時器中斷,就會通過上下文切換傳遞到對等執行緒。而對等執行緒執行一段時間,再傳遞迴主執行緒,依次類推。
執行緒的執行不同於程序,因為執行緒的上下文比程序的上下文小得多,所以執行緒上下文的效率要比程序的上下文切換快得多。另外,執行緒不像程序那樣,不是按照嚴格的父子層次來組織的。主執行緒和其他執行緒的區別僅在於它總是程序第一個執行的執行緒

多執行緒程式設計

介紹完執行緒的一些基礎知識,下面用C和C++分別實現多執行緒程式設計。

C++的多執行緒程式設計

#include <iostream>
#include <thread>

using namespace std;
void func()
{
    for(int i = 0; i < 5; ++i)
    {
        std::this_thread::sleep_for(std::chrono::milliseconds(500));
        cout << "thread id:" << this_thread::get_id() << " run func" <<
endl; } } int main() { cout << "mainthread id: " << this_thread::get_id() << endl; std::thread t1 = std::thread(func); // 申請執行緒並在執行緒中執行func函式 std::thread t2 = std::thread(func); // 申請執行緒並在執行緒中執行func函式 t1.join(); // 等待t1執行緒結束 t2.join(); // 等待t2執行緒結束 return 0; }

以下程式的輸出如下:

mainthread id: 1
thread id:2 run func
thread id:3 run func
thread id:2 run func
thread id:3 run func
thread id:2 run func
thread id:3 run func
thread id:2 run func
thread id:3 run func
thread id:2 run func
thread id:3 run func

主執行緒的執行緒id為1,當執行緒物件申請開始,執行緒就已經開始執行func函式。id為2的執行緒和id為3的執行緒每隔500ms進行輸出。而join函式的呼叫,會讓主執行緒等待子執行緒執行結束後在進行退出。

C的多執行緒程式設計

#include <stdio.h>
#include <pthread.h>
#include <unistd.h>

void* func(void *val)
{
    for(int i = 0; i < 5; ++i)
    {
        usleep(500 * 1000);
        printf("thread id: 0x%x, run func\n", (unsigned int)pthread_self());
    }

    return NULL;
}

int main()
{
    printf("mainthread id: 0x%x\n", (unsigned int)pthread_self());
    pthread_t t1;
    pthread_t t2;

    pthread_create(&t1, NULL, func, NULL);	// 建立執行緒
    pthread_create(&t2, NULL, func, NULL);	// 建立執行緒

    pthread_join(t1, NULL);		// 等待t1執行緒結束	
    pthread_join(t2, NULL);		// 等待t1執行緒結束

    return 0;
}

以下程式的輸出如下:

mainthread id: 0xf7da0740
thread id: 0xf7d9f700, run func
thread id: 0xf759e700, run func
thread id: 0xf7d9f700, run func
thread id: 0xf759e700, run func
thread id: 0xf7d9f700, run func
thread id: 0xf759e700, run func
thread id: 0xf759e700, run func
thread id: 0xf7d9f700, run func
thread id: 0xf7d9f700, run func
thread id: 0xf759e700, run func

輸出效果和C++實現類似,兩個執行緒交替呼叫func函式。該環境跑在linux。