一、創建一個線程,並回收,驗證線程是全局變量共享的
#include<stdio.h>
#include<unistd.h>
#include<pthread.h>
//exit()在這個庫中
#include<stdlib.h>
//線程函數
void* ptf(void* arg)
{
printf("this is child pthread!,pthread_id is %lu\n",pthread_self());
//return NULL;
pthread_exit(NULL);
}
int main()
{
pthread_t pt_id;
//用於存放線程建立返回值
int ret;
ret=pthread_create(&pt_id,NULL,ptf,NULL);
//pt_id,會在創建好線程後,賦值,同時驗證了線程全局變量共享
printf("child pthread id is %lu\n",pt_id);
if(ret!=0)
{
printf("create child pthread error!\n");
exit(1);
}
//阻塞等待
pthread_join(pt_id,NULL);
printf("process id is %u\n",getpid());
return 0;
//pthread_exit((void*)1);
}
二、創建一個線程,子線程設置參數, 父線程回收
#include<stdio.h>
#include<unistd.h>
#include<pthread.h>
//exit()在這個庫中
#include<stdlib.h>
typedef struct{
int a;
char b;
}exit_t;
void* ptf(void* arg)
{
printf("this is child pthread!,pthread_id is %lu\n",pthread_self());
exit_t*ret=(exit_t*)malloc(sizeof(exit_t));
ret->a=100;
ret->b='b';
//return NULL;
//強制轉換成void*
pthread_exit((void*)ret);
}
int main()
{
pthread_t pt_id;
exit_t*retval=NULL;
int ret;
ret=pthread_create(&pt_id,NULL,ptf,NULL);
if(ret!=0)
{
printf("create child pthread error!\n");
exit(1);
}
//sleep(1);
//強制轉換成void**,因爲pthread_exit返回的是void*
pthread_join(pt_id,(void**)&retval);
printf("process id is %u\n",getpid());
printf("a is %d,b is %c\n",retval->a,retval->b);
free(retval);
pthread_exit((void*)1);
//return 0;
}
三、回收多個子進程
/*回收多個子線程*/
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<pthread.h>
int var=100;
void *tfn(void *arg) //每個子線程進行回收
{
int i;
i = (int)arg;
sleep(i); //輸出有順序
if(i == 1){
var = 333;
printf("var = %d\n",var);
return (void *)var;
}else if(i == 3){
var = 777;
printf("I'm %d th 線程,線程ID爲 %lu var = %d\n",i+1,pthread_self(),var);
pthread_exit((void *)var);
}else {
printf("I'm %d th 線程,線程ID = %lu\n var = %d\n",i+1,pthread_self(),var);
pthread_exit((void *)var);
}
return NULL;
}
int main(void)
{
pthread_t tid[5];
int i;
int *ret[5]; //保存 5個線程的退出值
for(i = 0;i < 5; i++)//循環創建多個子線程
pthread_create(&tid[i],NULL,tfn,(void*)i);
for(i=0;i < 5; i++){ //對多個子線程進行回收
pthread_join(tid[i],(void **)&ret[i]);
printf("-----------%d th ret = %d\n",i,(int)ret[i]);
}
printf("I'm main 線程 tid = %lu\t var = %d\n",pthread_self(),var);
//主控線程也打印777,原因是共享全局變量
sleep(i);
return 0;
}
#include<stdio.h>
#include<unistd.h>
#include<pthread.h>
//exit()在這個庫中
#include<stdlib.h>
#define n 5
int val;
void* ptf(void* arg)
{
int i;
i=(int)arg;
printf("i is %d\n",i);
val=100;
//sleep(i);
if(i<3)
{
//printf("this is child pthread!,pthread_id is %lu\n",pthread_self());
val=33;
//printf("a is %d,b is %c\n",ret->a,ret->b);
}
else
{
//printf("this is child pthread!,pthread_id is %lu\n",pthread_self());
val=44;
}
//return NULL;
//強制轉換成void*
pthread_exit((void*)val);
}
int main()
{
pthread_t pt_id[n];
int *ret[n];
int i;
//創建多個線程,速度太快,相當於同時創建多個進程
for(i=0;i<n;i++)
{
//sleep(i);
//(void*)i 傳遞的是i的值,強制轉化成void*,傳地址的話沒有上鎖可能會產生多線程競爭
pthread_create(&pt_id[i],NULL,ptf,(void*)i);
}
for(i=0;i<n;i++)
{
//強制轉換成void**,因爲pthread_exit返回的是void*
pthread_join(pt_id[i],(void**)&ret[i]);
printf("a is %d\n",ret[i]);
}
pthread_exit((void*)1);
//return 0;
}
四、線程分離
#include<stdio.h>
#include<unistd.h>
#include<string.h>
#include<pthread.h>
void *tfn(void *arg)
{
int n=3;
while(n--){
printf("thread count %d\n",n);
sleep(1);
}
return (void *)1;
}
int main(void)
{
pthread_t tid;
void *tret;
int err;
pthread_create(&tid,NULL,tfn,NULL);
pthread_detach(tid); //讓線程分離 ----自動退出,無系統殘留資源
while(1){
//因爲線程分離,無需回收,所以阻塞等待返回錯誤代碼
err = pthread_join(tid,&tret);
printf("---------err= %d\n",err);
if(err != 0)
//根據錯誤代碼打印錯誤
fprintf(stderr,"thread error: %s\n",strerror(err));
else
fprintf(stderr,"thread exit code %d\n",(int)tret);
sleep(1);
}
return 0;
}
五、殺死線程,如果線程函數沒有系統調用函數的取消點,則必須自己添加取消點,才能殺死,printf底層調用了read函數,sleep底層調用了pause函數
/*三種退出線程的方法*/
#include<stdio.h>
#include<string.h>
#include<pthread.h>
void *tfn1(void *arg) //第一個線程
{
printf("thread 1 returning\n");
return (void *)111;
}
void *tfn2(void *arg) //第二個線程
{
printf("thread 2 exiting\n");
pthread_exit((void *)222);
}
void *tfn3(void *arg) //第三個線程
{
while(1){
printf("thread 3:I'm going to die in 3 seconds ....\n");
sleep(1);
//pthread_testcancel();//自己添加取消點
}
return (void *)666;
}
int main(void)
{
pthread_t tid;
void *tret = NULL;
pthread_create(&tid,NULL,tfn1,NULL);
pthread_join(tid,&tret);
printf("thread 1 exit code = %d\n\n",(int)tret);
pthread_create(&tid,NULL,tfn2,NULL);
pthread_join(tid,&tret);
printf("thread 2 exit code = %d\n\n",(int)tret);
pthread_create(&tid,NULL,tfn3,NULL);
sleep(3);
pthread_cancel(tid);
pthread_join(tid,&tret);
printf("thread 3 exit code = %d\n\n",(int)tret);
return 0;
}
六、手動初始化線程屬性,設置分離狀態,必須先初始化線程
#include<stdio.h>
#include<unistd.h>
#include<string.h>
#include<pthread.h>
void *tfn(void *arg)
{
int n=3;
while(n--){
printf("thread count %d\n",n);
sleep(1);
}
return (void *)1;
}
int main(void)
{
pthread_t tid;
void *tret;
int err;
#if 1
pthread_attr_t attr; //通過線程屬性類設置遊離態
//必須先初始化
pthread_attr_init(&attr);
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
pthread_create(&tid,&attr,tfn,NULL);
#else
pthread_create(&tid,NULL,tfn,NULL);
pthread_detach(tid); //讓線程分離 ----自動退出,無系統殘留資源
#endif
while(1){
err = pthread_join(tid,&tret);
printf("---------err= %d\n",err);
if(err != 0)
fprintf(stderr,"thread error: %s\n",strerror(err));
else
fprintf(stderr,"thread exit code %d\n",(int)tret);
sleep(1);
}
return 0;
}
七、設置線程棧的大小,設置線程屬性的綜合實例
#include<stdio.h>
#include<unistd.h>
#include<pthread.h>
#include<string.h>
#include<stdlib.h>
#define SIZE 0x100000
void *th_fun(void * arg)
{
while(1);
sleep(1);
}
int main(void)
{
pthread_t tid;
int err, detachstate,i=1;
pthread_attr_t attr;
size_t stacksize;
void *stackaddr;
pthread_attr_init(&attr);
pthread_attr_getstack(&attr,&stackaddr,&stacksize);
pthread_attr_getdetachstate(&attr,&detachstate);
if(detachstate == PTHREAD_CREATE_DETACHED)//默認是分離態
printf("thread detached\n");
else if(detachstate == PTHREAD_CREATE_JOINABLE)//默認非分離
printf("thread join\n");
else
printf("thread un known\n");
//設置線程分離
pthread_attr_setdetachstate(&attr,PTHREAD_CREATE_DETACHED);
while(1){
//在堆上申請內存,指定線程棧的起始地址和大小
stackaddr = malloc(SIZE);
if(stackaddr == NULL){
perror("malloc");
exit(1);
}
stacksize = SIZE;
pthread_attr_setstack(&attr,stackaddr,stacksize);//藉助線程的屬性,修
改線程棧空間大小
err = pthread_create(&tid,&attr,th_fun,NULL);
if(err != 0){
printf("%s\n",strerror(err));
exit(1);
}
printf("%d\n",i++);//i表示循環創建多少次
}
pthread_attr_destroy(&attr);
return 0;
}