與傳統進程相比,用線程來實現相同的功能有如下優點:
(1)系統資源消耗低。
(2)速度快。
(3)線程間的數據共享比進程間容易的多。
二、多線程編程簡單實例#include <stdio.h>#include <stdlib.h>#include <errno.h>#include <pthread.h>voidthread1_routine(void){ PRintf("new thread:thread_id is %u, process_id is %u/n", pthread_self(), getpid());}voidthread2_routine(void){ printf("new thread:thread_id is %u, process_id is %u/n", pthread_self(), getpid());}intmain(void){ pthread_t pt; printf("old thread:thread_id is %u, process_id is %u/n", pthread_self(), getpid()); pthread_create(&pt, NULL, (void *)thread1_routine, NULL); pthread_create(&pt, NULL, (void *)thread2_routine, NULL); usleep(5); return(0);}運行結果如下(可以看出在同一個進程中有三個不同的線程同時在運行):
![]()


線程屬性包括綁定屬性、分離屬性、堆棧地址、堆棧大小和優先級。其中分離屬性、堆棧地址以及堆棧大小的介紹可參考http://www.CUOXin.com/nufangrensheng/p/3522583.html。系統默認的是非邦定、非分離、缺省1M的堆棧、與父進程同樣級別的優先級。在pthread_create中,把第二個參數設置為NULL的話,將采用默認的屬性配置。
1、綁定屬性
線程可以分為用戶級線程和內核級線程兩種(可參考http://blog.csdn.net/songjinshi/article/details/9042265以及http://www.xuebuyuan.com/1380720.html),而綁定屬性正是設置用戶級線程和內核級線程之間的關系。
綁定屬性分為兩種:綁定和非綁定。在綁定屬性下,一個用戶級線程固定分配給一個內核線程,因為CPU時間片的調度是面向內核線程(輕量級進程)的,因此具有 綁定屬性的線程可以保證在需要的時候總有一個內核線程與之對應。在非綁定屬性下,用戶線程和內核線程的關系不是始終固定的,而是由系統根據實際情況分配的。

2、優先級





生產者消費者實例(多線程+互斥量):
#include <stdio.h>#include <pthread.h>#include <sched.h>void *producter_f(void *arg);void *consumer_f(void *arg);int buffer_has_item = 0;pthread_mutex_t mutex;int running = 1;int main(void){ pthread_t consumer_t; pthread_t producter_t; pthread_mutex_init(&mutex, NULL); pthread_create(&producter_t, NULL, (void *)producter_f, NULL); pthread_create(&consumer_t, NULL, (void *)consumer_f, NULL); sleep(1); /* 等待線程創建完畢 */ running = 0; pthread_join(consumer_t, NULL); pthread_join(producter_t, NULL); pthread_mutex_destroy(&mutex); return(0);}void *producter_f(void *arg){ while(running) { if(buffer_has_item < 10) /* 最多允許生產10個 */ { pthread_mutex_lock(&mutex); buffer_has_item++; printf("product, total: %d/n", buffer_has_item); pthread_mutex_unlock(&mutex); } }}void *consumer_f(void *arg){ while(running) { if(buffer_has_item > 0) /* 緩沖區為空時不允許再消費 */ { pthread_mutex_lock(&mutex); buffer_has_item--; printf("consume, total: %d/n", buffer_has_item); pthread_mutex_unlock(&mutex); } }}編譯運行結果如下:
![]()

五、線程中使用信號量
(此處使用的信號量是POSIX無名信號量:http://www.CUOXin.com/nufangrensheng/p/3564306.html)
線程的信號量與進程的信號量類似,使用線程的信號量可以高效地完成基于線程的資源計數。信號量實際上是一個非負的整數計數器,用來實現對公共資源的控制。在公共資源增加的時候,信號量的值增加;公共資源消耗的時候,信號量的值減少;只有當信號量的值大于0時,才能允許訪問信號量所代表的公共資源。





生產者消費者實例(多線程+信號量):
#include <stdio.h>#include <pthread.h>#include <semaphore.h>void *producter_f(void *arg);void *consumer_f(void *arg);sem_t sem;int running = 1;int main(void){ pthread_t consumer_t; pthread_t producter_t; sem_init(&sem, 0, 16); pthread_create(&producter_t, NULL, (void *)producter_f, NULL); pthread_create(&consumer_t, NULL, (void *)consumer_f, NULL); sleep(1); running = 0; pthread_join(consumer_t, NULL); pthread_join(producter_t, NULL); sem_destroy(&sem); return(0);}void *producter_f(void *arg){ int semval = 0; while(running) { usleep(1); sem_post(&sem); sem_getvalue(&sem, &semval); printf("product, total: %d/n", semval); }}void *consumer_f(void *arg){ int semval = 0; while(running) { usleep(1); sem_wait(&sem); sem_getvalue(&sem, &semval); printf("consume, total: %d/n", semval); }}編譯運行如下:![]()
![]()

更多關于線程的介紹可參考http://www.CUOXin.com/nufangrensheng/p/3518114.html及其后續博文。
新聞熱點
疑難解答