线程的创建、终止、等待和分离

1、线程创建
int pthread_create(pthread_t thread,const pthread_attr_t *attr,void (start_routine) (void ),void *arg);
参数:

  • thread:返回线程ID(用户态)
  • attr:设置线程属性,不易设为NULL;
  • start_routine:是一个函数地址,线程启动时要执行的函数
  • arg:传给线程启动函数的参数

返回值:成功返回0;失败返回错误编码。
功能:创建一个线程,并且将线程加入当前进程

2、线程终止的三种方法:

  • 从线程函数 return,这种方法对于主进程不适用,从main函数return相当于调用exit
  • 一个线程可以调用pthread_cancel终止同一个进程中的一个线程。
  • 线程可以自己调用pthread_exit()终止自己,哪个线程调用,哪个线程的终止。

我们使用的是pthread_wait()来终止一个线程
void pthread_exit(void *value_ptr)

  • 功能:使用函数退出线程,这是线程的主动行为
  • 参数:value_ptr:value_ptr不要指向一个局部变量,用来保存线程退出以后的返回值。这个返回值很少使用。
  • 返回值:无返回值,和进程一样,线程结束时无法返回到他的调用者。

取消一个线程
int pthread_cancel(pthread_t thread);

  • 概念:ptthread_canel调用并不等待线程的终止,他只是提出请求,线程提出请求后会继续执行,直到达到取消点
  • 参数,线程ID;
  • 返回值:成功返回0,失败返回错误码

3、线程等待(等待状态,和pthread_detach()相对应)
一个线程创建出来的默认属性是joinable。
int pthread_join(pthread_t thread, void **retval)

  • 以阻塞的方式等待thread指定的线程结束,当函数返回时 ,被等待线程的资源将会被回收 ,如果线程已经结束,那么该函数会立即返回,并且thread指定的线程必须是joinable的。
  • 参数:thread:线程标识符,即线程 ID; retval:用户定义的指针,用来存储被等待线程的返回值。
  • 返回值:0代表成功,否则表示失败,,返回的是错误码。
  • 应用:代码中如果没有pthread_join主线程会很快结束,从而使整个进程结束,从而使创建的线程没有机会执行就结束了,加入pthread_join后,主线程会一直等待直到等待的线程结束才会自己结束,使创建的线程有机会执行。
  • 目的,为了获取线程的退出状态

由于一个进程的多个线程是共享数据段的,因此通常在线程退出的情况下,退出进程所占的资源并不会随着线程的终止而得到释放。所以可以通过pthread_join()来同步释放资源。

4、返回线程的id
pthread_t pthread_self(void)
返回值:谁调用这个函数,返回谁的线程ID

5、线程分离
线程分离(不可等待状态):
pthread_detach()和pthread_join()不可以同时使用
int pthread_detach(pthread_t thread);

  • 功能:分离线程,指定线程退出后自动释放资源,设置线程的分离属性(将等待属性变为分离属性),即将jionable属性改为分离属性,不关心线程的退出状态。
  • 由来:调用pthread_join()后,如果 线程没有运行结束,调用者会被阻塞,但是有些情况下我们不希望如此,所以可以在子线程中 加入以下代码:pthread_detach(pthread_self())

父线程调用pthread_detach(thread_id)(非阻塞,可立即返回)
将该子线程的状态设置为detached,则该线程运行结束后会自动释放所有资源。

你可能感兴趣的:(操作系统)