激情久久久_欧美视频区_成人av免费_不卡视频一二三区_欧美精品在欧美一区二区少妇_欧美一区二区三区的

服務器之家:專注于服務器技術及軟件下載分享
分類導航

Linux|Centos|Ubuntu|系統(tǒng)進程|Fedora|注冊表|Bios|Solaris|Windows7|Windows10|Windows11|windows server|

香港云服务器
服務器之家 - 服務器系統(tǒng) - Linux - Linux 多線程編程實例

Linux 多線程編程實例

2019-09-09 15:58腳本之家 Linux

這篇文章主要介紹了Linux 多線程編程實例,本文講解了多線程 VS 多進程的概念、程序設計邏輯以及每個步驟的代碼實例,需要的朋友可以參考下

一、多線程 VS 多進程

和進程相比,線程有很多優(yōu)勢。在Linux系統(tǒng)下,啟動一個新的進程必須分配給它獨立的地址空間,建立眾多的數據表來維護代碼段和數據。而運行于一個進程中的多個線程,他們之間使用相同的地址空間。正是這樣,同一進程下的線程之間共享數據空間,數據可以相互使用,并且線程間切換也要更快些,可以更有效的利用CPU。

二、程序設計

[注] 頭文件<pthread.h> 編譯時要加載動態(tài)庫 libpthread.a,使用 -lpthread
 
1、創(chuàng)建線程
2、等待線程
3、關閉線程
4、退出清除
 
1、創(chuàng)建線程
 

復制代碼
代碼如下:

int pthread_create(pthread_t *tidp, const pthread_attr_t *attr, void *(*start_rtn)(void), void *arg)

tidp為線程id,是函數分配的值,所以要傳一個 pthread_t 的地址。
attr線程屬性,通常為空。
start_rtn為線程要執(zhí)行的函數,返回值為空指針,參數為后面的*arg
若成功則返回0,否則返回出錯編號。
 
例:

 

 

復制代碼
代碼如下:

#include<stdio.h>
#include<pthread.h></p> <p>void *func1(void *arg){ //原函數聲明
int i;
for(i=0;i<5;i++){
printf("this is func1! The num is %d\n",*(int*)arg); //將空指針轉換為int型指針
sleep(1);
}
}</p> <p>void *func2(int *m){ //自定義類型聲明,也可以定義非指針類型,但是在create時會有警告,因為非地址并不能改變傳入的值
int i;
for(i=0;i<5;i++){
printf("this is func2! The num is %d\n",*m);
(*m)++;
sleep(1);
}
}</p> <p>int main(){
pthread_t id1,id2;
int num = 5;
int *p = &num;
if(pthread_create(&id1,NULL,(void *)func1,(void *)p) != 0){
printf("thread1 create error!\n");
return -1;
}
if(pthread_create(&id2,NULL,(void *)func2,&num) != 0){
printf("thread2 create error!\n");
return -1;
}
pthread_join(id1,NULL); //等待線程結束 
pthread_join(id2,NULL);
printf("Running complete!\n");
return 0;</p> <p>
}

 

運行結果:

 

復制代碼
代碼如下:

[fsy@localhost process]$ gcc thC.c -o thC -lpthread -g
[fsy@localhost process]$ ./thC
this is func2! The num is 5
this is func1! The num is 6
this is func2! The num is 6
this is func1! The num is 7
this is func2! The num is 7
this is func1! The num is 8
this is func2! The num is 8
this is func1! The num is 9
this is func2! The num is 9
this is func1! The num is 10
Running complete!
[fsy@localhost process]$

 


2、等待線程

[注]當調用pthread_create函數時,線程并沒有開始執(zhí)行,主進程應有等待,比如用sleep,或者用更專業(yè)的函數:pthread_join
 

復制代碼
代碼如下:

int pthread_join(pthread_t tid, void **rval_ptr)

調用函數可以阻塞調用線程,直到指定的線程終止。
tid為等待退出線程的id,rval_ptr為函數的返回值。是指向指針的指針,可以置空。
 
例:

復制代碼
代碼如下:

#include<stdio.h>
#include<pthread.h>
#include<stdlib.h></p> <p>void *func(int *p){
int *num=(int *)malloc(sizeof(int)); //必須動態(tài)創(chuàng)建,原因可以參考我動態(tài)分配內存的博客
printf("Please input the number: ");
scanf("%d",num);
return (void *)num; //類型是pthread_create的參數規(guī)定的
}</p> <p>int main(){
pthread_t pth;
void *a;
if(pthread_create(&pth,NULL,(void *)func,NULL) != 0){
printf("create thread error!\n");
return 1;
}
pthread_join(pth,&a); //指向空指針的指針
printf("get the num from the thread, it's %d\n",*(int *)a);
return 0;
}

 

3、終止線程

線程終止有以下三種方式:

1、線程從函數中返回
2、線程可以別其他函數終止
3、線程自己調用pthread_exit函數
 

復制代碼
代碼如下:

void pthread_exit(void *rval_ptr)

rval_ptr為線程退出返回值的指針,即函數返回值。

 

4、退出清除
 

復制代碼
代碼如下:

void pthread_cleanup_push(void (*rtn)(void*), void *arg)

rtn為清除函數,arg是清除函數的參數

復制代碼
代碼如下:

void pthread_cleanup_pop(int execute)

當execute 非0時執(zhí)行清除函數。為0時不執(zhí)行。

 

從pthread_cleanup_push的調用點到pthread_cleanup_pop之間的程序段中,如果有終止進程的動作,如調用pthread_exit或異常終止(不包括return),就會執(zhí)行pthread_cleanup_push()所指定的清理函數。多個嵌套匹配時,就近匹配。
 
例:
 

復制代碼
代碼如下:

#include<stdio.h>
#include<pthread.h></p> <p>void *clean(char *argv){
printf("clean is called by %s\n",argv);
return NULL;
}
void *func1(void *argv){
printf("welcome enter the func1!\n");
pthread_cleanup_push((void*)clean,"the first time call!");
pthread_cleanup_push((void*)clean,"the second time call!");
if(argv){
return (void *)1; //第二次運行將此句注掉
}
pthread_cleanup_pop(0);
pthread_cleanup_pop(1);
return (void *)0;
}</p> <p>void *func2(void *argv){
sleep(1); //兩個線程運行先后不確定
printf("welcome enter the func2!\n");
pthread_cleanup_push((void*)clean,"the first time call!");
pthread_cleanup_push((void*)clean,"the second time call!");
if(argv){
pthread_exit(NULL);
}
pthread_cleanup_pop(0);
pthread_cleanup_pop(0);
return (void *)0;
}</p> <p>
int main(){
pthread_t tid1,tid2;
if(pthread_create(&tid1,NULL,(void *)func1,(void *)1) != 0){
printf("thread1 create error!\n");
return 1;
}</p> <p> if(pthread_create(&tid2,NULL,(void *)func2,(void *)1) != 0){
printf("thread2 create error!\n");
return 1;
}
pthread_join(tid1,NULL);
pthread_join(tid2,NULL);
return 0;
}

 

運行結果:
 

復制代碼
代碼如下:

[fsy@localhost process]$ gcc thClean.c -o thclean -lpthread
[fsy@localhost process]$ ./thclean
welcome enter the func1!
welcome enter the func2!
clean is called by the second time call! //此處先2后1
clean is called by the first time call!
[fsy@localhost process]$ vim thClean.c
[fsy@localhost process]$ gcc thClean.c -o thclean -lpthread
[fsy@localhost process]$ ./thclean
welcome enter the func1!
clean is called by the first time call! //second已經被pop
welcome enter the func2!
clean is called by the second time call!
clean is called by the first time call!
[fsy@localhost process]$ 

延伸 · 閱讀

精彩推薦
384
主站蜘蛛池模板: 网站一区 | 国产成人综合在线 | 国产亚洲精品综合一区 | 欧美另类69xxxxx 视频 | 视频一区免费观看 | 欧美不卡三区 | 国产精品视频不卡 | 成人午夜天堂 | 一级电影免费看 | 国产日韩在线视频 | 精品呦女 | 亚洲特黄妇女高潮 | 九九热在线精品视频 | 久久精品23 | 久久精品视频首页 | 欧美一级毛片欧美一级成人毛片 | 日本在线一区二区 | 国产精品国产成人国产三级 | 亚洲日色 | 99riav国产在线观看 | 免费一级特黄欧美大片勹久久网 | 成人一级毛片 | 久久久人 | 成人午夜视频在线观看 | 成人在线视频在线观看 | 国产精品久久久久久久久久东京 | 成人情欲视频在线看免费 | 激情亚洲一区二区 | 成人免费毛片片v | 日韩剧情片 | 黄色电影免费提供 | 羞羞网站 | 一级大黄毛片 | 欧美成a人片在线观看久 | 欧洲精品色 | 成人在线免费观看网址 | 韩国精品一区二区三区四区五区 | 欧美成人福利 | 久久成年网 | 男女一边摸一边做羞羞视频免费 | 欧美黑人伦理 |