linux-基礎-線程

大綱:
1.線程基礎知識
2.線程編程
一.線程基礎知識
1.線程和進程比較
和進程相比,是一種非常節儉的多任務操作方式。啓動一個新的進程必須分配給它獨立的地址空間,建立衆多的數據表來維護它的代碼段,堆棧段
數據段。一個進程中的多個線程,他們之間使用相同的地址空間,線程間彼此切換時間遠遠小於進程
linux系統下,多線程遵循posix線程接口p.pthread,多線程包含頭文件pthread.h和libpthread.a的庫
多線程
二線程-編程
1.創建線程
int pthread_create(pthread_t *tidp,const pthread_attr_t *attr,
(void*)(start_rtn)(void),void *arg);
tidp:線程id
attr:線程屬性(通常爲空)
stat_rtn:線程要執行的函數
arg:stat_rtn的參數
若線程創建成功,則返回0。若線程創建失敗,則返回出錯編號
2.線程的編譯
pthread的庫不是linux系統的庫,所以編譯的時候
gcc filename -lpthread
實例1:

#include <pthread.h>
#include<sys/types.h>
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<sys/stat.h>
#include<string.h> 
void *thread1(void){
  int i;
  for(i=0;i<50;i++){
     printf("it is thread1\n");
     sleep(1);
  }
}
void *thread2(void){
  for(i=0;i<50;i++){
     int i;
     printf("it is thread2\n");
     sleep(2);
  } 
}
int main(){
  int i=0,ret1=0,ret2=0;
  pthread_t id1,id2;
  ret1=pthread_create(&id1,NULL,(void *)thread1,NULL);
  if(ret1){
     printf("create error\n");
     return -1;
  }
  ret2=pthread_create(&id1,NULL,(void *)thread2,NULL);
  if(ret2){
     printf("create error\n");
     return -1;
  }
pthread_join(id1,NULL);
pthread_join(id2,NULL); 
return 0;
} 

運行結果
這裏寫圖片描述
實例2:

#include <pthread.h>
#include<sys/types.h>
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<sys/stat.h>
#include<string.h>
void *create(void *arg){
   int *num;
   num=(int*)arg;
   printf("create is %d \n",*num);
   return (void*) 0;
   }
int main(int argc,char *argv[]){
   pthread_t tidp;
   int ret;
   int test=4;
   int *attr=&test;
   ret=pthread_create(&tidp,NULL,create,(void*)attr);
   if(ret!=0){
     printf("create error\n");
     return -1;
   }
   sleep(1);
   printf("create success\n")
   return 0;
}

這裏寫圖片描述
3.線程的等待
int thread_join(pthread_t tid,void **rval_ptr);
功能:阻塞線程調用,直到指定線程終止
tid:等待退出的線程
rval_ptr:線程退出返回的指針
返回值 : 0代表成功。 失敗,返回的則是錯誤號

#include <pthread.h>
#include<sys/types.h>
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<sys/stat.h>
#include<string.h>
void *thread(void *str){
   int i;
   for(i=0;i<10;i++){
      printf("this is the thread:%d\n",i);
      return 0;//0表示程序正常執行,非0表示異常
    }
}
int main(){
   pthread_t pth;
   int i;
   int ret;
   ret=thread_create(&pth,NULL,thread,(void*)(i));
   pthread_join(pth,NULL);
   printf(".....\n");
   for(i=0;i<10;i++){
      sleep(1);
      printf("it is the main thread : %d\n",i);
   }
   return 0;
}

運行結果
這裏寫圖片描述
註釋掉pthread_join(pth,NULL);之後的執行結果
這裏寫圖片描述
4.線程標識
pthread_t pthread_self(void)//獲得當前線程id
5.線程清除
a.void Pthread_cleanup_push(void (rtn)(void),void *arg);//註冊清理函數rtn,這個函數有一個參數arg。
rtn:清除函數
arg:清除函數的參數
什麼時候進行調用Pthread_cleanup_push
1)調用pthread_exit。
2)作爲對取消線程請求(pthread_cancel)的響應。
3)以非0參數調用pthread_cleanup_pop。
什麼時候不可以調用Pthread_cleanup_push
1)如果線程只是由於簡單的返回而終止的,則清除函數不會被調用。
2)如果pthread_cleanup_pop被傳遞0參數,則清除函數不會被調用,但是會清除處於棧頂的清理函數。
b.void Pthread_cleanup_pop(int execute)//清除函數彈出清除棧
execute:非0執行,0不執行。不管發生上訴那種情況,pop都將刪除push調用建立的清理處理程序。

#include<pthread.h>
#include<sys/types.h>
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<sys/stat.h>
#include<string.h>
#include<fcntl.c>
void *thr_fun1(void *arg){
   print("thread 1 start");
   pthread_cleanup_push((void*)clean,"thread 1 frist");
   pthread_cleanup_push((void*)clean,"thread 1 second");
   printf("thread 1 push complete\n");
   if(arg){
       return((void*));
       }
       pthread_cleanup_pop(0);
       pthread_cleanup_pop(0);
       return((void*)1);
    }
void *thr_fun2(void *arg){
   print("thread 2 start");
   pthread_cleanup_push((void*)clean,"thread 2 frist");
   pthread_cleanup_push((void*)clean,"thread 2 second");
   printf("thread 2 push complete\n");
   if(arg){
       pthread_exit((void*)2);
       }
       pthread_cleanup_pop(0);//取消第一個線程處理程序 
       pthread_cleanup_pop(0);
       pthread_exit((void*)2);
    }
int main(void){    
    int ret1,ret2;    
    pthread_t tid1,tid2;    
    void *tret;    
    ret1 = pthread_create(&tid1,NULL,thr_fun1,(void *)1);//創建線程    
    ret2 = pthread_create(&tid2,NULL,thr_fun2,(void *)2);    
    if(ret!=0){    
        printf("create error\n");
        return -1;    
    }    
    pthread_join(tid1,&tret); //阻塞線程tid1      
    printf("thread 1 exit code\n");    
    pthread_join(tid2,&tret);       
    printf("thread 2 exit code/n");    
    exit(0);     
}

1.push與pop一定是成對出現的,其實push中包含”{“而pop中包含”}”,少一個不行。
2.push可以有多個,同樣的pop也要對應的數量,遵循”先進後出原則”。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章