1. 程式人生 > >Linux關於多執行緒技術

Linux關於多執行緒技術

執行緒的概念

在一個程式裡的多個執行路線就叫做執行緒(thread)。更準確的定義是:執行緒是“一個程序內部的控制序列” 一切程序至少都有一個執行執行緒

執行緒的優點

建立一個新執行緒的代價要比建立一個新程序小得多 與程序之間的切換相比,執行緒之間的切換需要作業系統做的工作至少在理論上要少很多 執行緒佔用的資源要比程序少很多

執行緒的函式使用

與執行緒有關的函式構成了一個完整的系列,絕大多數函式的名字都是以“pthread_”打頭的 要使用這些函式庫,要通過引入標頭檔案<pthread.h> 連結這些執行緒函式庫時要使用編譯器命令的“-lpthread”選項

建立執行緒函式

int  pthread_create(pthread_t *thread,  pthread_attr_t *attr, void*(*start_routine)(void*), void *arg);

函式引數的理解:

thread:新執行緒建立成功後,儲存新執行緒的識別符號 attr:設定執行緒的屬性,一般不需要什麼特殊的屬性,直接傳           NULL即可 start_routine: 是個函式地址,執行緒啟動後要執行的函式 arg:傳給執行緒啟動函式的引數“void* (*start_routine)(void*) ”表示需要我們傳遞的一個函式地址,該函式以一個指向void的指標為引數,返回的也是一個指向void的指標。 呼叫成功時返回值是“0”,如果失敗則返回一個錯誤。

接下來就來一段程式碼:(下面程式碼實現兩個執行緒,task_set_name函式是給執行緒設定名字)

#include<stdio.h>
#include<unistd.h>
#include<pthread.h>
#include<stdlib.h>
#include<string.h>
#include<sys/syscall.h>
#include<sys/prctl.h>
int task_set_name(const char *name)
{
    char thread_name[128]={0};
    if(!name)
        return -1;
    snprintf(thread_name,sizeof(thread_name),"%s(%ld)",name,syscall(SYS_gettid));
    prctl(PR_SET_NAME,thread_name,0,0,0);
    return 0;
}

void *routine1 (void *arg[])
{
    char *pbuf=(char *)arg;
    int i;
    task_set_name("aa");
    printf("%s,pid = 0x%08x\n",pbuf,(int)pthread_self());
    for(;i<5;i++)
    {
        putchar('A');
        fflush(stdout);
        sleep(1);
    }
    pthread_exit("pthread1");
    return 0; 
}

void *routine2(void *arg[])
{
    char *pbuf=(char *)arg;
    int i;
    printf("%s,pid = 0x%08x\n",pbuf,(int)pthread_self());
    for(;i<5;i++)
    {
        putchar('B');
        fflush(stdout);
        sleep(1);
    }
    pthread_exit("pthread2");
    return 0; 
}

int main(int argc,char *argv[])
{
    int i;
    char *thread_buf = "this is first!\n";
    pthread_t tid,tid1;
    //1.建立執行緒1
    int ret = pthread_create(&tid,NULL,routine1,thread_buf);
    if(ret < 0)
    {
       fprintf(stderr,"thread create failed:%s\n",strerror(ret)); 
    }
    ret = pthread_create(&tid1,NULL,routine2,thread_buf);
    if(ret != 0)
    {
      fprintf(stderr,"thread create faile:%s\n",strerror(ret));
    }
    sleep(2);
    for(i = 0;i<5;i++)
    {
        putchar('c');
        fflush(stdout);
    }

    //2.等待執行緒回收
    char *pre;
    pthread_join(tid,(void**)&pre);
    printf("======%s\n",pre);
    pthread_join(tid1,(void**)&pre);
    printf("=====%s\n",pre);
    return 0;
}

程式碼結果

首先我看看到兩個執行緒被建立,接下來就是兩個執行緒裡面實現rountine1和rountine2都是個函式地址,執行緒啟動後要執行的函式

分別執行輸出A和B,接下來就是主函式輸出c,最後就是執行緒回收