線程: 在一個程序的位址空間中執行多個線程 ---- 強調共享
線程是程序中的一個實體。
線程私有: 線程id
上下文資訊 (包括各種寄存器的值、程式計數器和棧指針)
(私有)棧空間 errno變量 信号屏蔽字 排程優先級
此時:POSIX标準 編譯時 加上 -lpthread
線程與程序的差別:
1、程序是具有一定獨立功能的程式關于某個資料集合上的一次運作活動,程序是系統進行資源配置設定和排程的一個獨立機關;
線程是程序的一個實體。
2、程序 強調 獨占,線程 強調 共享。
3、線程私有【 線程id
上下文資訊 (包括各種寄存器的值、程式計數器和棧指針)
(私有)棧空間 errno變量 信号屏蔽字 排程優先級 】
4、二者均可并發執行。
一、線程控制:
1、建立線程:
int pthread_create(pthread_t *thread, const pthread_attr_t *attr,
void *(*start_routine) (void *), void *arg);
//參數:線程 id,線程 屬性,線程 狀态,線程 參數
//傳回值:成功 0;失敗 錯誤碼
2、等待線程:
int pthread_join(pthread_t thread, void **retval); //參數:線程 id,傳回值
3、終止線程:
1)從線程函數内部 return 結束 //value_ptr指向的存放:return 傳回值
2)從線程函數調用 pthread_exit()函數 //value_ptr指向的存放:pthread_exit 參數
void pthread_exit(void *retval);
3)線程被取消 pthread_cancel()
int pthread_cancel(pthread_t thread); //value_ptr指向的存放:PTHREAD_CANCELED (-1)
pthread_t pthread_self(void); //線程id
執行個體:
//my_thread.c
#include<stdio.h>
#include<pthread.h>
void *thread_run(void *arg)
{
// sleep(10);
int count=5;
while(count-- > 0)
{
printf("this is thread,Code: %d\n",pthread_self());
sleep(1);
}
// return (void*)1; //終止線程1:return
// pthread_exit((void*)2); //終止線程2:pthread_exit
return NULL; //終止線程3:pthread_cancel
}
int main()
{
pthread_t tid; //主線程
int ret=pthread_create(&tid,NULL,thread_run,NULL); //建立線程
int count=10;
while(count-- > 0)
{
printf("This is Main-Thread,Code: %d\n",pthread_self());
sleep(1);
}
pthread_cancel(tid); //終止線程3:pthread_cancel
void *status=0;
ret=pthread_join(tid,&status);
if(ret == 0)
{
printf("thread is success,Code: %d\n",(int)status);
}
return 0;
}
運作結果:
終止線程:
總結:
終止程序的三種方法運作結果大體相同,但傳回值不同,return 的傳回值和exit的參數及PTHREAD_CANCELED (值為-1)。
二、線程分離: 線程的一種屬性
線程是可結合的(joinable)或者是分離的(detached)。
由于調用pthread_join後,如果該線程沒有運作結束,調用者會被阻塞,在有些情況下我們并不希望如此。這時可以在 子線程中加入代碼 pthread_detach(pthread_self())
或者 父線程調用 pthread_detach(thread_id)(非阻塞,可立即傳回)。
這将該子線程的狀态設定為分離的,這樣一來,該線程運作結束後會自動釋放所有資源。
//thread_detach.c
#include<stdio.h>
#include<pthread.h>
void* thread1(void *arg)
{
int count=5;
while(count-- > 0)
{
printf("this is thread1:%d,thread_t:%u\n",(int)arg,pthread_self());
sleep(1);
}
return (void*)1;
}
void* thread2(void *arg)
{
int count=5;
while(count-- > 0)
{
printf("this is thread2:%d,thread_t:%u\n",(int)arg,pthread_self());
sleep(1);
}
pthread_exit((void*)2);
}
void* thread3(void *arg)
{
int count=5;
while(count-- > 0)
{
printf("this is thread3:%d,thread_t:%u\n",(int)arg,pthread_self());
sleep(1);
}
return NULL;
}
int main()
{
pthread_t tid1,tid2,tid3;
pthread_create(&tid1,NULL,thread1,(void*)1);
pthread_create(&tid2,NULL,thread2,(void*)2);
pthread_create(&tid3,NULL,thread3,(void*)3);
sleep(2);
pthread_cancel(tid3);
pthread_detach(tid1);
void *ret=NULL;
int res=pthread_join(tid1,&ret);
printf("tid1 return,res:%d\n",res);
res=pthread_join(tid2,&ret);
printf("tid2 pthread_exit,res:%d\n",res);
res=pthread_join(tid3,&ret);
printf("tid3 pthread_cancel,res:%d\n",res);
return 0;
}