1. 程式人生 > >Linux執行緒---執行緒建立、等待、分離、優先順序

Linux執行緒---執行緒建立、等待、分離、優先順序

建立執行緒,等待執行緒終止

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

void f(void)
{
    for(int i=0; i<3; ++i)
        printf ("This is a pthread.\n");
}

int main(void)
{
    pthread_t id;  

    // 執行緒建立
    int ret = pthread_create(&id,    // 執行緒識別符號
            NULL,            // 執行緒屬性
/* 如果未指定屬性物件,則該物件為NULL,系統會建立具有以下屬性的預設執行緒: 1、程序範圍 2、非分離 3、預設棧和預設棧大小 4、零優先順序 還可以用pthread_attr_init()建立預設屬性物件,然後使用該屬性物件來建立預設執行緒。 */ (void*)f, // 執行緒執行函式的起始地址 NULL); // 執行函式的引數
printf("%d\n", ret); // 返回值ret // 0: 建立成功 // EAGAIN: 超出了系統限制,如建立的執行緒太多。 // EINVAL: 屬性值無效。 if(ret != 0) { printf("Create pthread error!\n"); exit(1); } for(int i=0; i<3; ++i) { printf("This is the main process.\n"); // 等待一個執行緒的結束 // 指定的執行緒必須位於當前程序中,不可以是分離執行緒
// 應用程式可回收與已終止執行緒關聯的任何資料儲存空間 // 程式碼中如果沒有pthread_join()函式,主函式會很快結束從而使整個程序結束 // 從而使建立的執行緒沒有機會開始執行就結束了 int ret1 = pthread_join(id, // 被等待執行緒的識別符號 NULL); // 使用者定義的指標,儲存被等待執行緒返回值 // 返回值ret1 // 0: 成功 // ESRCH: 沒有找到與給定的執行緒ID相對應的執行緒 // EDEADLK: 將出現死鎖,如一個執行緒等待其本身,或者執行緒A和執行緒B互相等待 // EINVAL: 與給定的執行緒ID相對應的執行緒是分離執行緒 return 0; } return 0; }

這裡寫圖片描述

分離執行緒

pthread_detach()可以顯式用於分離執行緒,儘管建立時是可連線的。

  建立一個執行緒預設的狀態是joinable, 如果一個執行緒結束執行但沒有被join,則它的狀態類似於程序中的Zombie Process,即還有一部分資源沒有被回收(退出狀態碼),所以建立執行緒者應該使用pthread_join()來等待執行緒執行結束,並可得到執行緒的退出程式碼,回收其資源(類似於wait,waitpid)。但是呼叫pthread_join()後,如果該執行緒沒有執行結束,呼叫者會被阻塞,在有些情況下我們並不希望如此,比如在Web伺服器中當主執行緒為每個新來的連結建立一個子執行緒進行處理的時候,主執行緒並不希望因為呼叫pthread_join而阻塞(因為還要繼續處理之後到來的連結),這時可以在子執行緒中加入程式碼
  

pthread_detach(pthread_self());

或在主執行緒中呼叫
pthread_detach(thread_id);//非阻塞,可立即返回
這將使該子執行緒的狀態設定為detached,則該執行緒執行結束後會自動釋放所有資源。

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

int count = 0;

void print()
{
    printf("%d\n", count++);
    pthread_exit(0);
    sleep(1000);
}

int main()
{
    pthread_t id;

    while(1)
    {
        pthread_create(&id, NULL, (void*)print, NULL);
        pthread_detach(id);
    }
    return 0;
}

執行緒優先順序

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

void myfunc(void *a)
{
    printf("a: %d\n", *(int*)a);
    pthread_exit(0);  // 執行緒退出
}

int main()
{
    pthread_attr_t attr;
    pthread_t tid;
    struct sched_param param;
    int newprio = 20;

    // 先取執行緒優先順序,然後修改,最後放回去

    pthread_attr_init(&attr);  // 建立預設屬性物件
    pthread_attr_getschedparam(&attr, &param);  // 獲取執行緒屬性
    printf("priority1: %d\n", param.sched_priority);

    param.sched_priority = newprio;
    pthread_attr_setschedparam(&attr, &param);  // 設定執行緒屬性
    printf("priority2: %d\n", param.sched_priority);

    int myarg = 3;
    int ret = pthread_create(&tid, &attr, (void*)myfunc, (void*)&myarg);
    printf("ret: %d\n", ret);

    pthread_join(tid, NULL);  
    return 0;
}

這裡寫圖片描述