實現併發服務器通常都是父進程accept一個鏈接,而後fork一個子進程,該子進程處理與該鏈接對端的客戶之間的通訊。可是fork是昂貴,耗資源和時間。而線程是輕量級線程,它的建立比進程的建立塊10-100倍。在同一進程內除了共享全局變量外還共享:服務器
大多數數據;進程指令; 打開的文件; 信號處理函數信號處置; 當前工做目錄;用戶ID和組ID多線程
不過每一個線程有各自的資源:‘併發
線程ID; 寄存器集合了棧了errno; 信號掩碼; 優先級函數
pthread_create函數spa
#include <pthread.h>線程
int pthread_create(pthread_t *tid, const pthread_attr_t *attr, void *(*func)(void *), void *arg);code
一個進程的每一個線程都由一個線程ID標識。每一個線程有不少屬性,好比優先級大小,初始棧大小,是否應該成爲一個守護線程等等進程
pthread_join函數資源
#include <pthread.h>同步
int pthread_join(pthread_t *tid, void **status);
該函數相似與waitpid
pthread_self函數
#include <pthread.h>
int pthread_self(void);
每一個線程使用pthread_self得到自身的線程ID
pthread_detach函數
#include <pthread.h>
int pthread_detach(pthread_t tid);
一個線程或者是可匯合的,或者是脫離的。當一個可匯合的線程終止時,它的線程ID和退出狀態將留存到另外一個線程對它調用pthread_join。脫離的線程像守護線程,當他們終止時,全部相關資源都被釋放.
pthread_exit函數
#include <pthread.h>
int pthread_exit(void *status);
結束一個線程
多線程程序的經典問題:多個線程同時修改一個共享變量(如全局變量)
#include <pthread.h> #include <stdio.h> int counter; void *doit(void*); int main(int argc, char **argv) { pthread_t tidA, tidB; pthread_create(&tidA, NULL, &doit, NULL); pthread_create(&tidB, NULL, &doit, NULL); pthread_join(tidA, NULL); pthread_join(tidB, NULL); return 0; } void *doit(void * arg) { int i, val; for(i=0; i<10; i++) { val = counter; printf("counter is %d\n", val+1); counter = val+1; } return NULL; }
上面程序的運行結果並非咱們想要的結果,由於線程的運行是併發運行的,也就是說counter值的修改的結果是不定的,如下爲運行結果
因此咱們應該引入同步機制,首先使用互斥量實現
#include <pthread.h> #include <stdio.h> int counter; pthread_mutex_t counter_mutex; void *doit(void*); int main(int argc, char **argv) { pthread_t tidA, tidB; pthread_create(&tidA, NULL, &doit, NULL); pthread_create(&tidB, NULL, &doit, NULL); pthread_join(tidA, NULL); pthread_join(tidB, NULL); return 0; } void *doit(void * arg) { int i, val; for(i=0; i<10; i++) { pthread_mutex_lock(&counter_mutex); val = counter; printf("counter is %d\n", val+1); counter = val+1; pthread_mutex_unlock(&counter_mutex); } return NULL; }
使用在對counter值進行修改以前進行上鎖操做,修改以後,進行解鎖操做