Linux下的线程
一、線程的優點
與傳統進程相比,用線程來實現相同的功能有如下優點:
(1)系統資源消耗低。
(2)速度快。
(3)線程間的數據共享比進程間容易的多。
二、多線程編程簡單實例
#include <stdio.h> #include <stdlib.h> #include <errno.h> #include <pthread.h>void thread1_routine(void) {printf("new thread:thread_id is %u, process_id is %u\n",pthread_self(), getpid()); } void thread2_routine(void) {printf("new thread:thread_id is %u, process_id is %u\n",pthread_self(), getpid()); }int main(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.cnblogs.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.cnblogs.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.cnblogs.com/nufangrensheng/p/3518114.html及其后續博文。
轉載于:https://www.cnblogs.com/nufangrensheng/p/3581962.html
總結
- 上一篇: ExtJs Ext.panel.Pane
- 下一篇: Linux 线程实现机制分析