初試Linux下的線程編程

來源:互聯網
上載者:User

標籤:pthread   線程   

如何建立線程

Linux下一般使用POSIX線程庫,也叫pthread。編寫線程函數需要注意的是線程函數的傳回型別必須是void*;程式編譯的時候記得要連結上pthread庫,方法:-lpthread

簡單的線程程式

下面是簡單的線程程式,主程式裡建立了2個線程,分別列印不同的資訊。每個線程用pthread_create函數來建立。每個線程運行完程式之後,必須使用pthread_join函數來等待線程結束,也就是回收線程。一旦兩個線程都退出後,主程式就會退出。

#include <stdio.h>#include <stdlib.h>#include <string.h>#include <unistd.h>#include <errno.h>#include <pthread.h>void error(char *msg){    fprintf(stderr, "%s :  %s\n", msg, strerror(errno) );    exit(1);}void* hello(void *a){    int i = 0;    for(i = 0; i < 5; i++)    {        sleep(1);        puts("hello linux!");    }    return NULL;}void* goodbye(void *a){    int i = 0;    for(i = 0; i < 5; i++)    {        sleep(1);        puts("goodbye linux!");    }    return NULL;}int main(int argc, char const *argv[]){    pthread_t t0;    pthread_t t1;    if(pthread_create(&t0, NULL, hello, NULL) == -1)        error("cant  creat pthread t0");    if(pthread_create(&t1,NULL, goodbye, NULL) == -1)        error("cant  creat pthread t1");    void* result;    if(pthread_join(t0, &result) == -1)        error("cant join pthread t0");    if(pthread_join(t1, &result) == -1)        error("cant join pthread t1");    return 0;}

如果編譯器沒有添加-lpthread,就會出現下面的錯誤

[email protected]:~/test_code# gcc -Wall pthread.c -o pthread/tmp/cc5KEYbr.o:在函數‘main’中:pthread.c:(.text+0xec):對‘pthread_create’未定義的引用pthread.c:(.text+0x116):對‘pthread_create’未定義的引用pthread.c:(.text+0x138):對‘pthread_join’未定義的引用pthread.c:(.text+0x15a):對‘pthread_join’未定義的引用collect2: error: ld returned 1 exit status

成功編譯後,結果如下:

root@zengwh:~/test_code# gcc -Wall pthread.c -lpthread -o pthreadroot@zengwh:~/test_code# ./pthread goodbye linux!hello linux!goodbye linux!hello linux!goodbye linux!hello linux!hello linux!goodbye linux!hello linux!goodbye linux!
多個線程訪問共用資料

下面的程式,同時建立10個線程,每個線程公用一個函數,都是將全域變數number 減1000,等所有線程結束之後,再列印出變數的值,看是否等於0.

#include <stdio.h>#include <stdlib.h>#include <string.h>#include <unistd.h>#include <errno.h>#include <pthread.h>int number = 10000;void error(char *msg){    fprintf(stderr, "%s :  %s\n", msg, strerror(errno) );    exit(1);}void* func(void *a){    int i = 0;    for (i = 0; i < 1000; ++i)    {        number -= 1;    }    return NULL;}int main(int argc, char const *argv[]){    pthread_t thread[10];    int j = 0;    printf("begining: the number is : %d\n", number );    for (j = 0; j < 10; ++j)    {        if (pthread_create(&thread[j], NULL, func, NULL) == -1)            error("cant  creat pthread t0");    }    void* result;    for (j = 0; j < 10; ++j)    {        if (pthread_join(thread[j], &result) == -1)            error("cant  creat pthread t0");    }    printf("finally: the number is : %d\n", number );    return 0;}

程式運行結果如下:

[email protected]:~/test_code# ./pthread begining: the number is : 10000finally: the number is : 882[email protected]:~/test_code# ./pthread begining: the number is : 10000finally: the number is : 801[email protected]:~/test_code# ./pthread begining: the number is : 10000finally: the number is : 501[email protected]:~/test_code# ./pthread begining: the number is : 10000finally: the number is : 634[email protected]:~/test_code# ./pthread begining: the number is : 10000finally: the number is : 887

每次啟動並執行結果都不一樣。線程最大的優點在於可以同時運行多個不同任務,並訪問相同的資料,但訪問相同的資料也成為了線程的缺點。上面程式的結果就是線程撞車,結果是不可預測的。

建立互斥鎖

為了讓多個線程可以訪問共用資料且不會發生撞車,一種簡單辦法就是建立互斥鎖。

pthread_mutex_t a_lock = PTHREAD_MUTEX_INITIALIZER;

互斥鎖必須是一個全域變數,這樣才能對所有有可能發生撞車的線程可見。pthread_mutex_lock()函數只允許一個線程運行,其他線程處於等待。然後調用pthread_mutex_unlock()函數解鎖,其他線程可以進入。

pthread_mutex_lock(&a_lock);/*需要訪問的共用資料*/pthread_mutex_unlock(&a_lock);

增加鎖後的程式

#include <stdio.h>#include <stdlib.h>#include <string.h>#include <unistd.h>#include <errno.h>#include <pthread.h>int number = 10000;pthread_mutex_t number_lock = PTHREAD_MUTEX_INITIALIZER; void error(char *msg){    fprintf(stderr, "%s :  %s\n", msg, strerror(errno) );    exit(1);}void* func(void *a){    int i = 0;    pthread_mutex_lock(&number_lock);    for (i = 0; i < 1000; ++i)    {        number -= 1;    }    pthread_mutex_unlock(&number_lock);    printf("the number is : %d\n", number );    return NULL;}int main(int argc, char const *argv[]){    pthread_t thread[10];    int j = 0;    printf("begining: the number is : %d\n", number );    for (j = 0; j < 10; ++j)    {        if (pthread_create(&thread[j], NULL, func, NULL) == -1)            error("cant  creat pthread t0");    }    void* result;    for (j = 0; j < 10; ++j)    {        if (pthread_join(thread[j], &result) == -1)            error("cant  creat pthread t0");    }    printf("finally: the number is : %d\n", number );    return 0;}
需要注意的是
  • 要控制碼中鎖的數量,不然會使程式變得很慢;
  • 減少線程需要訪問的共用資料的數量,程式會更高效地進行

初試Linux下的線程編程

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.