Linux編程基礎——線程概述

來源:互聯網
上載者:User

有的時候,我們需要在一個基礎中同時運行多個控制流程程。例如:一個圖形介面的下載軟體,在處理下載任務的同時,還必須響應介面的對任務的停止,刪除等控制操作。這個時候就需要用到線程來實現並行作業。

和訊號處理函數的控制在處理完訊號之後就結束不同的時,而多線程的控制流程程可以長期並存,作業系統會在各線程之間調度和切換,就像在多個進程之間調度和切換一樣,但建立線程開銷要比進程小得多。因此,線程往往也被稱作輕量級的進程。

由於同一進程的多個線程共用同一地址空間,資料區段是共用的,如果定義一個全域變數,在各線程中都可以訪問到。但有,些資源依然是每個線程各有一份的:

  • 線程id
  • 上下文,包括各種寄存器的值、程式計數器和棧指標
  • 棧空間
  • errno變數
  • 訊號屏蔽字
  • 調度優先順序

我們一般用到的是由POSIX標準定義的線程庫函數,稱為POSIX thread或者pthread。在Linux上線程函數位於libpthread共用庫中,因此在編譯時間要加上-lpthread選項。

建立線程

在POSIX庫中,建立線程是通過函數實現的,它的聲明如下:

    #include <pthread.h>

    int pthread_create(pthread_t *thread, const pthread_attr_t *attr,

                        void *(*start_routine) (void *), void *arg);

它有四個參數,

  • 第一個參數thread為建立後的線程標識符的指標。
  • 第二個參數attr為線程屬性,可選為PTHREAD_CREATE_DETACHED(分離線程)和 PTHREAD _CREATE_JOINABLE(非分離線程),一般是直接用NULL。
  • 第三個參數start_routine為線程的運行函數
  • 第四個參數arg為線程運行函數的參數
  • 建立成功時,返回0,失敗是返回錯誤碼。這個和其它的系統函數失敗返回-1,由errno返回錯誤碼不大一樣。

一個簡單的樣本如下:

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

    void* thr_fn(void *arg)
    {
        pid_t pid = getpid();
        pthread_t tid = pthread_self();

        printf("%s pid %u tid %u (0x%x)\n", arg, (unsigned
int)pid,    (unsigned
int)tid, (unsigned
int)tid);

        return NULL;
    }

    int main(void)
    {
        pthread_t ntid = {0};

        int err = pthread_create(&ntid, NULL, thr_fn, (void*)"new thread: ");
        if (err != 0)
        {
            fprintf(stderr, "can't create thread: %s\n", strerror(err));
            exit(1);
        }

        void *tret;
        pthread_join(ntid, &tret);
        printf("thread exited\n");

        return 0;
    }

當我們編譯這段程式時,會發現如下錯誤:

    tianfang@linux-k36c:/mnt/share/test> make
    make: Warning: File `Makefile' has modification time 0.48 s in the future
    g++ -o run main.o
    main.o: In function `main':
    /mnt/share/test/main.cpp:20: undefined reference to `pthread_create'
    collect2: error: ld returned 1 exit status
    make: *** [run] Error 1
    tianfang@linux-k36c:/mnt/share/test>

這是一個連結錯誤,它的意思是找不到pthread_create函數的定義。這是因為在Linux上線程函數位於libpthread共用庫中,因此在編譯時間要加上-lpthread選項。

等待線程結束

有的時候,我們需要等待線程結束,此時才能繼續執行後面的事情。拿前面的例子來說,如果不等待線程結束,則主線程(main函數)會直接往下執行導致程式退出,線程函數都無法得到執行。

pthread庫中等待線程結束的函數是pthread_join,它的聲明如下:

    #include
<pthread.h>
    int pthread_join(pthread_t thread, void **retval);

它有兩個參數,第一個參數是線程標識符,第二個參數是個出參,使用者擷取線程函數的傳回值。pthread_join在前面的例子中已經有示範,這裡就不再介紹了。

終止線程

終止線程的方法一般來說有如下幾種:

  • 線程函數調用return終止自己
  • 線程調用pthread_exit終止自己
  • 線程可以調用pthread_cancel終止同一進程中的其它線程

其中,方法1和方法2都是通過結束線程函數來實現主動退出的,它們是比較常用的方法。方法3則是一種強制終止的做法,這個方法一個問題就是導致對象的解構函式可能無法執行,會出現資源泄漏,並不推薦用這種方法。

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.