Linux多线程基础学习(三)线程生命周期

来源:互联网 发布:淘宝联盟 易语言源码 编辑:程序博客网 时间:2024/05/29 19:48

初始线程/主线程

 

1、当c程序运行时,首先运行main函数。在线程代码中,这个特殊的执行流被称作初始线程或者主线程。你可以在初始线程中做任何普通线程可以做的事情。

2、主线程的特殊性在于,它在main函数返回的时候,会导致进程结束,进程内所有的线程也将会结束。这可不是一个好的现象,你可以在主线程中调用pthread_exit函数,这样进程就会等待所有线程结束时才终止。

3、主线程接受参数的方式是通过argc和argv,而普通的线程只有一个参数void*

4、在绝大多数情况下,主线程在默认堆栈上运行,这个堆栈可以增长到足够的长度。而普通线程的堆栈是受限制的,一旦溢出就会产生错误

 

 

上篇博客中的代码将41行代码注释掉

//sleep(1);


运行结果变为


看上去显得线程没有创建!这是为什么?

根据上面的描述可以解释这个现象。因为原来有sleep函数可以让原来的主线程延迟1s时间结束,但是去掉后,主线程在print自己的ID后就结束了,同时导致程序的进程结束,而此时其他的子线程可能还没有创建完成,或者没有执行到输出自己ID的语句处。因此看上去新线程没有创建。

如上所示。在42行处加入下面两行代码,就能解决这个问题。

int re;pthread_exit(&re);


线程的生命周期

线程从创建、运行到结束总是处于下面五个状态之一:新建状态、就绪状态、运行状态、阻塞状态及终止状态。

  

 状态含义就绪线程能够运行,但是在等待可用的处理器运行线程正在运行,在多核系统中,可能同时有多个线程在运行阻塞线程在等待处理器以外的其他条件终止线程从启动函数中返回,或者调用pthread_exit函数,或者被取消    

就绪状态:

当线程刚被创建时就处于就绪状态,或者当线程被解除阻塞以后也会处于就绪状态。就绪的线程在等待一个可用的处理器,当一个运行的线程被抢占时,它立刻又回到就绪状态

运行:

当处理器选中一个就绪的线程执行时,它立刻变成运行状态

阻塞:

线程会在以下情况下发生阻塞:试图加锁一个已经被锁住的互斥量,等待某个条件变量,调用singwait等待尚未发生的信号,执行无法完成的I/O信号,由于内存页错误

终止:

线程通常启动函数中返回来终止自己,或者调用pthread_exit退出,或者取消线程

线程的分离属性:

分离一个正在运行的线程并不影响它,仅仅是通知当前系统该线程结束时,其所属的资源可以回收。一个没有被分离的线程在终止时会保留它的虚拟内存,包括他们的堆栈和其他系统资源,有时这种线程被称为“僵尸线程”。创建线程时默认是非分离的

 

如果线程具有分离属性,线程终止时会被立刻回收,回收将释放掉所有在线程终止时未释放的系统资源和进程资源,包括保存线程返回值的内存空间、堆栈、保存寄存器的内存空间等。

终止被分离的线程会释放所有的系统资源,但是你必须释放由该线程占有的程序资源。由malloc或者mmap分配的内存可以在任何时候由任何线程释放,条件变量、互斥量、信号灯可以由任何线程销毁,只要他们被解锁了或者没有线程等待。但是只有互斥量的主人才能解锁它,所以在线程终止前,你需要解锁互斥量

分离线程 pthread_detach(3C)是pthread_join(3C)的替代函数,可回收创建时detachstate属性设置为PTHREAD_CREATE_JOINABLE的线程的存储空间。

pthread_detach语法

int pthread_detach(thread_t tid);

#include <pthread.h>pthread_t tid;int ret;/* detach thread tid */ret = pthread_detach(tid);


pthread_detach()函数用于指示应用程序在线程tid终止时回收其存储空间。如果tid尚未终

止,pthread_detach()不会终止该线程。


 

 

0 0
原创粉丝点击