线程2:线程创建等待及退出

线程创建等待及退出

1.Linux上线程开发API概要
多线程开发在 Linux 平台上已经有成熟的 pthread 库支持。其涉及的多线程开发的最基本概念主要包含三点:线程,互斥锁,条件。其中,线程操作又分线程的创建,退出,等待 3 种互斥锁则包括 4 种操作,分别是创建,销毁,加锁和解锁条件操作有 5 种操作:创建,销毁,触发,广播和等待。其他的一些线程扩展概念,如信号灯等,都可以通过上面的三个基本元素的基本操作封装出来。详细请见下表:
  在这里插入图片描述
2.与线程自身相关API
线程创建

#include <pthread.h>
int pthread_create(pthread_t *restrict tidp, const pthread_attr_t *restrict attr, void *(*start_rtn)(void *), void *restrict arg);
// 返回:若成功返回0,否则返回错误编号在这里插入代码片

pthread_create成功返回时,由tidp指向的内存单元被设置为新创建线程的线程ID。attr参数用于定制各种不同的线程属性,暂可以把它设置为NULL,以创建默认属性的线程。
  新创建的线程从start_rtn函数的地址开始运行,该函数只有一个无类型指针参数arg。如果需要向start_rtn函数传递的参数不止一个,那么需要把这些参数放到一个结构中,然后把这个结构的地址作为arg参数传入。
线程退出
  单个线程可以通过以下三种方式退出,在不终止整个进程的情况下停止它的控制流:
  1)线程只是从启动例程中返回,返回值是线程的退出码。
  2)线程可以被同一进程中的其他线程取消。
  3)线程调用pthread_exit:

#include <pthread.h>
int pthread_exit(void *rval_ptr);

rval_ptr是一个无类型指针,与传给启动例程的单个参数类似。进程中的其他线程可以通过调用pthread_join函数访问到这个指针。
线程等待

#include <pthread.h>
int pthread_join(pthread_t thread, void **rval_ptr);
// 返回:若成功返回0,否则返回错误编号

调用这个函数的线程将一直阻塞,直到指定的线程调用pthread_exit、从启动例程中返回或者被取消。如果例程只是从它的启动例程返回i,rval_ptr将包含返回码。如果线程被取消,由rval_ptr指定的内存单元就置为PTHREAD_CANCELED
  可以通过调用pthread_join自动把线程置于分离状态,这样资源就可以恢复。如果线程已经处于分离状态,pthread_join调用就会失败,返回EINVAL。
  如果对线程的返回值不感兴趣,可以把rval_ptr置为NULL。在这种情况下,调用pthread_join函数将等待指定的线程终止,但并不获得线程的终止状态。
  
综合使用例程:
 
代码:

#include <stdio.h>
#include <pthread.h>
//int pthread_create(pthread_t *restrict tidp, const pthread_attr_t *restrict attr, void *(*start_rtn)(void *), void *restrict arg);
// 返回:若成功返回0,否则返回错误编号----创建线程
void *func1(void*arg)//参数3:调用无类型指针API
{
    
    
 static int ret=10;//使函数结束,内存还在 
 static char *p = "t1 is run out";
 printf("t1:%ld thread is create\n",(unsigned long)pthread_self());
 //pthread_self():返回自身线程id,为pthread_t类型
 printf("t1:param is %d:\n",*((int*)arg));//转化为int*,再取值
 //pthread_exit((void *)&ret);
 pthread_exit((void *)p);
}
int main()
{
    
    
 int ret;//返回值
 pthread_t t1;
 int param=100;//参数4:调用时:将int*转化为void*.100:随便给的数
 //int *pret=NULL;
 char *pret1=NULL;
 ret=pthread_create(&t1,NULL,func1,(void*)&param);
 //参数1:指针指向t1,NULL:线程属性,参数3:启动线程调用的函数,参数4:打印的值
 if(ret==0)
 {
    
    
  printf("main函数创建线程t1成功\n");
 }
 printf("main:%ld\n",(unsigned long)pthread_self());
 //pthread_join(t1,NULL);//等待线程,主线程执行完不收回,等待子线程
 //pthread_join(t1,(void **)&pret);//等待线程,pret不指向null,指向ret
 pthread_join(t1,(void **)&pret1);//等待线程,pret不指向null,指向ret
  //printf("main:t1 quit:%d\n",*pret);
  printf("main:t1 quit:%s\n",pret1);
 return 0;
}

执行结果:

dazai@dazai:~$ gedit demo1.c
dazai@dazai:~$ gcc demo1.c -lpthread
dazai@dazai:~$ ./a.out 
main函数创建线程t1成功
t1:-1210954944 thread is create
t1:param is 100:
main:-1210951936
main:t1 quit:t1 is run out

猜你喜欢

转载自blog.csdn.net/weixin_40734514/article/details/108529425