Linux下的线程
一、線程的優(yōu)點
與傳統(tǒng)進程相比,用線程來實現(xiàn)相同的功能有如下優(yōu)點:
(1)系統(tǒng)資源消耗低。
(2)速度快。
(3)線程間的數(shù)據(jù)共享比進程間容易的多。
二、多線程編程簡單實例
#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); }運行結(jié)果如下(可以看出在同一個進程中有三個不同的線程同時在運行):
三、線程屬性
線程屬性包括綁定屬性、分離屬性、堆棧地址、堆棧大小和優(yōu)先級。其中分離屬性、堆棧地址以及堆棧大小的介紹可參考http://www.cnblogs.com/nufangrensheng/p/3522583.html。系統(tǒng)默認的是非邦定、非分離、缺省1M的堆棧、與父進程同樣級別的優(yōu)先級。在pthread_create中,把第二個參數(shù)設(shè)置為NULL的話,將采用默認的屬性配置。
1、綁定屬性
線程可以分為用戶級線程和內(nèi)核級線程兩種(可參考http://blog.csdn.net/songjinshi/article/details/9042265以及http://www.xuebuyuan.com/1380720.html),而綁定屬性正是設(shè)置用戶級線程和內(nèi)核級線程之間的關(guān)系。
綁定屬性分為兩種:綁定和非綁定。在綁定屬性下,一個用戶級線程固定分配給一個內(nèi)核線程,因為CPU時間片的調(diào)度是面向內(nèi)核線程(輕量級進程)的,因此具有 綁定屬性的線程可以保證在需要的時候總有一個內(nèi)核線程與之對應(yīng)。在非綁定屬性下,用戶線程和內(nèi)核線程的關(guān)系不是始終固定的,而是由系統(tǒng)根據(jù)實際情況分配的。
2、優(yōu)先級
四、線程互斥
生產(chǎn)者消費者實例(多線程+互斥量):
#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); /* 等待線程創(chuàng)建完畢 */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) /* 最多允許生產(chǎn)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) /* 緩沖區(qū)為空時不允許再消費 */{pthread_mutex_lock(&mutex);buffer_has_item--;printf("consume, total: %d\n", buffer_has_item);pthread_mutex_unlock(&mutex);}} }編譯運行結(jié)果如下:
?
五、線程中使用信號量
(此處使用的信號量是POSIX無名信號量:http://www.cnblogs.com/nufangrensheng/p/3564306.html)
線程的信號量與進程的信號量類似,使用線程的信號量可以高效地完成基于線程的資源計數(shù)。信號量實際上是一個非負的整數(shù)計數(shù)器,用來實現(xiàn)對公共資源的控制。在公共資源增加的時候,信號量的值增加;公共資源消耗的時候,信號量的值減少;只有當(dāng)信號量的值大于0時,才能允許訪問信號量所代表的公共資源。
生產(chǎn)者消費者實例(多線程+信號量):
#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);} } 編譯運行如下:?
更多關(guān)于線程的介紹可參考http://www.cnblogs.com/nufangrensheng/p/3518114.html及其后續(xù)博文。
轉(zhuǎn)載于:https://www.cnblogs.com/nufangrensheng/p/3581962.html
總結(jié)
- 上一篇: ExtJs Ext.panel.Pane
- 下一篇: 在存储过程中如何使用另一个存储过程返回的