pthread
POSIX thread為POSIX標準執行緒.定義thread的建立及使用方法
pthread.h中常用的有:
pthread_create、pthread_dispath、pthread_mutex_lock(互斥鎖定)、pthread_mutex_unlock(互斥解鎖)
所有pthread.h可用的function可參考 POSIX thread (pthread) libraries
http://www.yolinux.com/TUTORIALS/LinuxTutorialPosixThreads.html
ps
若在linux下gcc編譯,需加-lpthread參數
ex:
gcc thread.c -o thread -lpthread
……………………………………………..
常見函數說明
pthread_create()
建立thread
函數原形如下
int pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine) (void *), void *arg);
參數說明如下
pthread_t *thread: thread id
const pthread_attr_t *restrict attr:thread屬性
void *(*start_routine) (void *):指定要做為thread的function
void *arg:給thread的參數
ps:
thread建立成功後,函數會傳回0
若建立失敗則回傳錯誤代碼,常見代碼為EAGAIN和EINVAL
EAGAIN表示建立的thread數量已超過系統限制的thread數量
EINVAL表示thread屬性不正確
ex:
void printmsg(void);
.... omit ...
pthread_t tid;
pthread_create(&tid, NULL, (void *) printmsg, NULL);
.... omit ...
ex
void *printmsg_a(void *arg);
void *printmsg_b(void *arg);
.... omit ...
pthread_t tid1, tid2;
pthread_create(&tid1, NULL, &printmsg_a, NULL);
pthread_create(&tid2, NULL, &printmsg_b, NULL);
.... omit ...
ex
void *printmsg(void *arg); //argv[1]代入arg
.... omit ...
pthread_t tid;
pthread_attr_t attr;
pthread_attr_init(&attr);
char *argv[];
pthread_create(&tid, &attr, printmsg, argv[1]);
.... omit ...
ex:
void *printmsg( void *arg ){.... //message代入arg
.... omit ...
pthread_t tid1, tid2;
const char *message1 = "thread1";
const char *message2 = "thread2";
iret1 = pthread_create( &tid1, NULL, printmsg, (void*) message1);
iret2 = pthread_create( &tid2, NULL, printmsg, (void*) message2);
.... omit ...
pthread_join()
等待指定的thread結束
函數原型如下
int pthread_join(pthread_t thread, void **thread_return);
參數說明如下
pthread_t thread: thread id
void **thread_return: 用來儲存thread的回傳值
ps:
當等待指定的thread結束時,該函數會被收回
ex:
pthread_join(id,NULL);
pthread_exit()
thread自己結束
函數原型如下
void pthread_exit(void *retval);
ex:
pthread_exit(0);
pthread_key_create
建立thread全域變數
ex
#define NUMTHREADS 3
pthread_key_t glob_var_key;
pthread_t threads[NUMTHREADS];
int i;
pthread_key_create(&glob_var_key,NULL);
for (i=0; i < NUMTHREADS; i++){
pthread_create(&threads[i],NULL,thread_func,NULL);
}
for (i=0; i < NUMTHREADS; i++){
pthread_join(threads[i], NULL);
}
...omit...
void* thread_func(void *arg){
pthread_setspecific(glob_var_key, &glob_var);
...omit...
……………………………………………………………………….
常見範例
顯示資訊
ray@localhost# vi thread.c
#include
#include
void thread(void){
int i;
for(i=0;i<2;i++)printf("This is a thread n");
}
int main(void){
pthread_t id;
int i,ret;
pthread_create(&id,NULL,(void *) thread,NULL);
for(i=0;i<2;i++)printf("This is the process n");
pthread_join(id,NULL);
return (0);
}
ray@localhost# gcc thread.c -o thread -lpthread
ray@localhost# ./thread
This is the process
This is the process
This is a thread
This is a thread
ps
每次結果不一樣,這是thread和main process爭奪CPU資源的結果
讀取外部參數做計算
ray@localhost# vi sum_by_thread.c
#include
#include
int sum;
void *runner(void *param);
int main(int argc, char *argv[]){
pthread_t tid;
pthread_attr_t attr;
pthread_attr_init(&attr);
pthread_create(&tid,&attr,runner,argv[1]);
pthread_join(tid,NULL);
printf("sum=%dn",sum);
}
void *runner(void *param){
int i, upper= atoi(param);
sum=0;
if(upper>0){
for(i=1,i<=upper;i++)sum+=i;
}
pthread_exit(0);
}
ray@localhost# gcc sum_by_thread.c -o sum_by_thread -lpthread
ray@localhost# ./sum_by_thread 3
6
建立三個thread讀取三個檔案
ray@localhost# vi wordthread.c
#include
#include
#include
#define MAX_WLEN 20 //max length of a word
#define MAX_FLEN 6000 //max word in a FILE
#define NUMTID 3 //number of thread
///////////thread
char wordall[3][MAX_FLEN];
void rfile(char ta[2][20]);
////////////////////////////////////////////////////////////////////////////////////
int main(int argc, char *argv[]){
int i;
///////////// read file by thread
pthread_t tid[NUMTID];
char tarray[NUMTID][2][20];
char buffer[1];
for(i=0;i< NUMTID;i++){
sprintf(buffer, "%d", i);
strcpy(tarray[i][0],buffer); //save thread id
strcpy(tarray[i][1],argv[i+1]); //save file path
pthread_create(&tid[i], NULL,(void *) rfile,tarray[i]);
buffer[0]=' 0 '; //clear array
}
for(i=0;i< NUMTID;i++){
pthread_join(tid[i],NULL);
}
/////////// collect word from all file
char word[MAX_WLEN];
char *token;
char c;
int totalword=0;
for(i=0;i< NUMTID;i++){
token = strtok(wordall[i], " ,.n");
while(token){
strcpy(word, token);
for(c=0;c printf("%s n", word);
totalword++;
token = strtok(NULL, " ,.n");
}
printf("total word is %d", totalword);
}
}
//////////////////////////////////////////////////
///////////read file in thread
void rfile(char ta[2][20]){
FILE *aptr;
char line[MAX_FLEN];
aptr = fopen(ta[1],"r");
while(!feof(aptr)){
fgets(line, MAX_FLEN, aptr);
if(feof(aptr)) break;
strcpy(wordall[atoi(ta[0])], line);
}
fclose(aptr);
pthread_exit(0);
}
}
ray@localhost# gcc wordthread.c -o wordthread -lpthread
ray@localhost# ./wordthread text1 text2 text3
system
linux
is
…omit..
total word is 9
…………………………………………………
refer
linux man-page http://man7.org/linux/man-pages/man3/
create a global variable http://stackoverflow.com/questions/15100824/how-do-i-create-a-global-variable-that-is-thread-specific-in-c-using-posix-threa
Linux C/C++多线程pthread实例 http://www.metsky.com/archives/550.html
Linux下的多線程編程 http://fanqiang.chinaunix.net/a4/b8/20010811/0905001105_b.html
台灣wiki pthread http://www.twwiki.com/wiki/Pthread