Linux多线程2-2_线程的生命周期

一、初始线程/主线程
1、当c程序运行时,首先运行main函数。在线程代码中,这个特殊的执行流被称作初始线程或者主线程。你可以在初始线程中做任何普通线程可以做的事情。
2、主线程的特殊性在于,它在main函数返回的时候,会导致进程结束,进程内所有的线程也将会结束。这可不是一个好的现象,你可以在主线程中调用pthread_exit函数,这样进程就会等待所有线程结束时才终止。
3、主线程接受参数的方式是通过argc和argv,而普通的线程只有一个参数void*
4、在绝大多数情况下,主线程在默认堆栈上运行,这个堆栈可以增长到足够的长度。而普通线程的堆栈是受限制的,一旦溢出就会产生错误

二、线程的创建
1、主线程是随着进程的创建而创建
2、其他线程可以通过调用函数来创建,主要调用pthread_create
3、请注意,新线程可能在当前线程从函数pthread_create返回之前就已经运行了,甚至新 线程可能在当前线程从函数pthread_create返回之前就已经运行完毕了。

三、实例:主线程的特殊性

#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
#include "include/pthread.h"



#ifndef _WIN64
#pragma comment(lib,".\\lib32\\pthreadVC2.lib")
//#pragma comment(lib,".\\lib32\\pthreadVCE2.lib")
//#pragma comment(lib,".\\lib32\\pthreadVSE2.lib")
#else
#pragma comment(lib,".\\lib64\\pthreadVC2.lib")
#endif // !



/*
*getpid()          获取进程ID
*pthread_self()    获取县城ID
*
*int pthread_create(pthread_t *thread,
*                     const pthread_attr_t *attr,
*                     void *(*start_routine) (void *),
*                 void *arg);
*第一个参数,新线程id,创建成功系统回填
*第二个参数,新线程到属性,NULL为默认属性
*第三个参数,新线程到启动函数
*第四个参数,传递给新线程
*
*主线程的接收的参数都放在argv[], 而参数的个数则由argc统计

*/

struct student
{
	int age;
	char name[20];
	char id[4];
};

void* thread_fun(void* stu) {

	//Sleep(2);
	student* a = (student*)stu;
	
	printf("student age is %d,name is %s ,id is %s \n", a->age,
		a->name,a->id);
	return (void*)0;

}
int main(int argc, char* argv[])
{
	pthread_t tid;
	int err;
	int *rval;

	struct student stu;
	stu.age = 20;
	memcpy(stu.name,"zhangsan",20);
	memcpy(stu.id,"007",5);

	err = pthread_create(&tid, NULL, thread_fun, (void*)&stu);

	if (err!=0)
	{
		printf("creat new thread failed\n");
		return 0;
	}
	
	
	
	int i;
	printf("main thread have %d args\n",argc);
	for (i = 0; i < argc; i++)
	{
		printf("main thread args is %s\n", argv[i]);
	}

	pthread_join(tid, (void**)&rval);
	//pthread_exit((void*)rval);

	return 0;

}

四、线程的四个基本状态

1、就绪:当线程刚被创建时就处于就绪状态,或者当线程被解除阻塞以后也会处于就绪状态。就绪的线程在等待一个可用的处理器,当一个运行的线程被抢占时,它立刻又回到就绪状态
2、运行:当处理器选中一个就绪的线程执行时,它立刻变成运行状态
3、阻塞:线程会在以下情况下发生阻塞:试图加锁一个已经被锁住的互斥量,等待某个条件变量,调用singwait等待尚未发生的信号,执行无法完成的I/O信号,由于内存也错误
4、终止:线程通常启动函数中返回来终止自己,或者调用pthread_exit退出,或者取消线程

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

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

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值