/* example.c*/
#include <stdio.h>
#include <pthread.h>
void thread(void)
{
int i;
for(i=0;i<3;i++)
printf("This is a pthread.\n");
}
int main(void)
{
pthread_t id;
int i,ret;
ret=pthread_create(&id,NULL,(void *) thread,NULL);
if(ret!=0){
printf ("Create pthread error!\n");
exit (1);
}
for(i=0;i<3;i++)
printf("This is the main process.\n");
pthread_join(id,NULL);
return (0);
}
我們編譯此程序:
gcc example1.c -lpthread -o example1
運(yùn)行example1,我們得到如下結(jié)果:
This is the main process.
This is a pthread.
This is the main process.
This is the main process.
This is a pthread.
This is a pthread.
再次運(yùn)行,我們可能得到如下結(jié)果:
This is a pthread.
This is the main process.
This is a pthread.
This is the main process.
This is a pthread.
This is the main process.
2.5 與線程取消相關(guān)的pthread函數(shù)
int pthread_cancel(pthread_t thread)
發(fā)送終止信號(hào)給thread線程,如果成功則返回0,否則為非0值。發(fā)送成功并不意味著thread會(huì)終止。
int pthread_setcancelstate(int state, int *oldstate)
設(shè)置本線程對(duì)Cancel信號(hào)的反應(yīng),state有兩種值:PTHREAD_CANCEL_ENABLE(缺。┖蚉THREAD_CANCEL_DISABLE,分別表示收到信號(hào)后設(shè)為CANCLED狀態(tài)和忽略CANCEL信號(hào)繼續(xù)運(yùn)行;old_state如果不為NULL則存入原來(lái)的Cancel狀態(tài)以便恢復(fù)。
int pthread_setcanceltype(int type, int *oldtype)
設(shè)置本線程取消動(dòng)作的執(zhí)行時(shí)機(jī),type由兩種取值:PTHREAD_CANCEL_DEFFERED和PTHREAD_CANCEL_ASYCHRONOUS,僅當(dāng)Cancel狀態(tài)為Enable時(shí)有效,分別表示收到信號(hào)后繼續(xù)運(yùn)行至下一個(gè)取消點(diǎn)再退出和立即執(zhí)行取消動(dòng)作(退出);oldtype如果不為NULL則存入運(yùn)來(lái)的取消動(dòng)作類型值。
關(guān)于作者
楊沙洲,男,現(xiàn)攻讀國(guó)防科大計(jì)算機(jī)學(xué)院計(jì)算機(jī)軟件方向博士學(xué)位。您可以通過(guò)電子郵件pubb@163.net 跟他聯(lián)系。
(c) Copyright IBM Corp. 2001, (c) Copyright IBM China 2001, All Right Reserved
關(guān)于 IBM | 隱私條約 | 使用條款 | 聯(lián)系 IBM
動(dòng)態(tài)方式是采用pthread_mutex_init()函數(shù)來(lái)初始化互斥鎖,API定義如下:
int pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t *mutexattr)
其中mutexattr用于指定互斥鎖屬性(見(jiàn)下),如果為NULL則使用缺省屬性。
pthread_mutex_destroy()用于注銷一個(gè)互斥鎖,API定義如下:
int pthread_mutex_destroy(pthread_mutex_t *mutex)
銷毀一個(gè)互斥鎖即意味著釋放它所占用的資源,且要求鎖當(dāng)前處于開(kāi)放狀態(tài)。由于在Linux中,互斥鎖并不占用任何資源,因此LinuxThreads中的pthread_mutex_destroy()除了檢查鎖狀態(tài)以外(鎖定狀態(tài)則返回EBUSY)沒(méi)有其他動(dòng)作。
注銷一個(gè)條件變量需要調(diào)用pthread_cond_destroy(),只有在沒(méi)有線程在該條件變量上等待的時(shí)候才能注銷這個(gè)條件變量,否則返回EBUSY。因?yàn)長(zhǎng)inux實(shí)現(xiàn)的條件變量沒(méi)有分配什么資源,所以注銷動(dòng)作只包括檢查是否有等待線程。API定義如下:
int pthread_cond_destroy(pthread_cond_t *cond)
2. 等待和激發(fā)
int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex)
int pthread_cond_timedwait(pthread_cond_t *cond, pthread_mutex_t *mutex, const struct timespec *abstime)
int sem_init(sem_t *sem, int pshared, unsigned int value)
這是創(chuàng)建信號(hào)燈的API,其中value為信號(hào)燈的初值,pshared表示是否為多進(jìn)程共享而不僅僅是用于一個(gè)進(jìn)程。LinuxThreads沒(méi)有實(shí)現(xiàn)多進(jìn)程共享信號(hào)燈,因此所有非0值的pshared輸入都將使sem_init()返回-1,且置errno為ENOSYS。初始化好的信號(hào)燈由sem變量表征,用于以下點(diǎn)燈、滅燈操作。
int sem_destroy(sem_t * sem)
被注銷的信號(hào)燈sem要求已沒(méi)有線程在等待該信號(hào)燈,否則返回-1,且置errno為EBUSY。除此之外,LinuxThreads的信號(hào)燈注銷函數(shù)不做其他動(dòng)作。
2. 點(diǎn)燈和滅燈
int sem_post(sem_t * sem)
點(diǎn)燈操作將信號(hào)燈值原子地加1,表示增加一個(gè)可訪問(wèn)的資源。
int sem_wait(sem_t * sem)
int sem_trywait(sem_t * sem)
sem_wait()為等待燈亮操作,等待燈亮(信號(hào)燈值大于0),然后將信號(hào)燈原子地減1,并返回。sem_trywait()為sem_wait()的非阻塞版,如果信號(hào)燈計(jì)數(shù)大于0,則原子地減1并返回0,否則立即返回-1,errno置為EAGAIN。
3. 獲取燈值
int sem_getvalue(sem_t * sem, int * sval)
讀取sem中的燈計(jì)數(shù),存于*sval中,并返回0。
int pthread_sigmask(int how, const sigset_t *newmask, sigset_t *oldmask)
設(shè)置線程的信號(hào)屏蔽碼,語(yǔ)義與sigprocmask()相同,但對(duì)不允許屏蔽的Cancel信號(hào)和不允許響應(yīng)的Restart信號(hào)進(jìn)行了保護(hù)。被屏蔽的信號(hào)保存在信號(hào)隊(duì)列中,可由sigpending()函數(shù)取出。
int pthread_kill(pthread_t thread, int signo)
向thread號(hào)線程發(fā)送signo信號(hào)。實(shí)現(xiàn)中在通過(guò)thread線程號(hào)定位到對(duì)應(yīng)進(jìn)程號(hào)以后使用kill()系統(tǒng)調(diào)用完成發(fā)送。
int sigwait(const sigset_t *set, int *sig)
掛起線程,等待set中指定的信號(hào)之一到達(dá),并將到達(dá)的信號(hào)存入*sig中。POSIX標(biāo)準(zhǔn)建議在調(diào)用sigwait()等待信號(hào)以前,進(jìn)程中所有線程都應(yīng)屏蔽該信號(hào),以保證僅有sigwait()的調(diào)用者獲得該信號(hào),因此,對(duì)于需要等待同步的異步信號(hào),總是應(yīng)該在創(chuàng)建任何線程以前調(diào)用pthread_sigmask()屏蔽該信號(hào)的處理。而且,調(diào)用sigwait()期間,原來(lái)附接在該信號(hào)上的信號(hào)處理函數(shù)不會(huì)被調(diào)用。
可見(jiàn),pthread_cleanup_push()帶有一個(gè)"{",而pthread_cleanup_pop()帶有一個(gè)"}",因此這兩個(gè)函數(shù)必須成對(duì)出現(xiàn),且必須位于程序的同一級(jí)別的代碼段中才能通過(guò)編譯。在下面的例子里,當(dāng)線程在"do some work"中終止時(shí),將主動(dòng)調(diào)用pthread_mutex_unlock(mut),以完成解鎖動(dòng)作。
pthread_cleanup_push(pthread_mutex_unlock, (void *) &mut);
pthread_mutex_lock(&mut);
/* do some work */
pthread_mutex_unlock(&mut);
pthread_cleanup_pop(0);