-------------------------------------------------------
Thu 22 Feb 12:21:12 GMT 2018
-------------------------------------------------------
第十二章 併發編程
-------------------------------------------------------
使用應用級併發的應用程序稱爲併發程序(concurrent program)
.現代操做系統提供3個基本的構造併發程序的方法:編程
+ 進程
+ I/O多路複用。(i/o multiplexing)
+ threads服務器
12.1 Concurrent programming with processes併發
The simplest way to build a concurrent program is
with processes, using familiar functions such as "fork",
"exec", and 'waitpid'.函數
12.2 基於I/O多路複用的併發編程post
基本思路是使用select函數,要求內核掛起進程,只有在一個或
多個I/O事件發生後,纔將控制返回應用程序。ui
#include <sys/select.h>
int select(int n,fd_set *fdset,NULL,NULL,NULL);操作系統
返回已準備好的描述符的非零的個數,error 爲 -1.線程
FD_ZERO(fd_set *fdset); //clear alll bits in fdset
FD_CLR(int fd, fd_set *fdset); //clear bit fd in fdset
FD_SET(int fd,fd_set *fdset);//turn on bit fd in fdset
FD_ISSET(int fd,fd_set *fdset);//Is bit fd in fdset on指針
select處理類型爲fd_set的集合,也叫作描述符集合。該集合是
一個大小爲n的位向量。接口
12.3 基於線程的併發編程
每一個線程都有本身的線程上下文(thread context),包括喲個惟
一的整數線程ID(thread ID, TID,棧,棧指針,程序計數器,通用
目的寄存器和條件碼。
12.3.2 Posix 線程(Pthreads)
它是c程序中處理線程的一個標準接口。
#include <pthread.h>
typedef void *(func)(void *);
int pthread_create(pthread_t *tid,pthread_addr_t *attr
, func *f, void *arg);
新線程能夠經過調用pthread_self函數來得到它本身的TID,
pthread_t pthread_self(void);
12.3.4 終止線程
+ 當頂層的線程例程返回時,線程會隱式地終止。
+ 經過調用pthread_exit函數,顯示地終止。若是主線程調用
pthread_exit,它會等待全部其餘對等線程終止,而後再終止
主線程和整個進程,返回值爲thread_return.
void pthread_exit(void *thread_return);
+ 某個對等線程調用Linux的exit函數,該函數終止進程及全部
與該進程相關的線程。
+ 另外一個對等線程經過以當前線程ID做爲參數調用
pthread_cancel函數來終止當前線程。
int pthread_cancel(pthread_t tid);
12.3.5 回收已終止線程的資源
線程經過調用pthread_join function等待其餘線程終止。
int pthread_join(pthread_t tid, void **thread_return);
12.3.6 分離線程(Detaching Threads)
At any point in time a thread is joinable or detached.
A joinable thread can be reaped and killed by other thread
. Its memory resources(such as the stack) are not freed
until it is reaped by another thread.
In contrast, a detached thread cannot be reaped or
killed by other threads. Its memory resources ard freed
automatically by the system when it terminates.
默認狀況下,線程被建立成可結合的。用pthread_detach函數
分離線程。
int pthread_detach(pthread_t tid);
12.3.7 初始化線程
函數pthread_once容許初始化與線程相關的狀態:
pthread_once_t once_control = PTHREAD_ONCE_INIT;
int pthread_once(pthread_once_t *once_control,
void (*init_routine)(void));
once_control變量是一個全局或者靜態變量,老是被初始化爲
PTHREAD_ONCE_INIT.
12.4 Shared variables in threaded programs
registers are never shared,whereas virtual memory is
always shard.
12.4.3 Shared variables
We say that a variables V is shared if and only if one
of its instances is referenced by more than one thread.
12.5 信號量同步線程
12.5.2 semaphore(信號量)
信號量s是具備非負整數的全局變量,只有兩種操做:(P,V):
+ s的初始值爲1
+ P(s): 若是s非零,p將s減1,並當即返回。若是s爲0,就
掛起這個線程,直到s變爲0,而一個V操做會重啓這個線
程。在重啓後,P操做將s減1,並將控制返回調研者
+ V(s): V操做將s加1。若是有線程阻塞在P操做等待s變爲
非零,那麼V操做會重啓這些線程中的一個,而後該線程
將s減1,完成它的操做。
#include <semaphore.h>
int sem_init(sem_t *sem,0,unsigned int value);
int sem_wait(sem_t *s); // P(s)
int sem_post(set_t *s); // V(s)
以提供互斥爲目的的二元信號量經常也稱爲互斥鎖(mutex).
12.5.4 利用信號量來調度共享資源
1,生產者-消費者問題
2,讀者-寫着問題
12.5.5 綜合:基於預線程化的併發服務器(pre_threading)
+ 函數pthread_once用法:
int byte_cnt;
sem_t mutex;
void init_echo_cnt(void)
{
sem_init(&mutex,0,1);
byte_cnt = 0;
}
pthread_once_t once = PTHREAD_ONCE_INIT;
pthread_once(&once,init_echo_cnt);
12.6 使用線程提升並行性
-------------------------------------------------------Fri 2 Mar 13:49:52 GMT 2018