【校招 --阶段一 系统编程】线程控制

1 线程终止

如果需要只终止某个线程而不终止整个进程,可以有三种方法:

  1. 从线程函数return。这种方法对主线程不适用,从main函数return相当于调用exit。
  2. 线程可以调用pthread_ exit终止自己。
  3. 一个线程可以调用pthread_ cancel终止同一进程中的另一个线程。

pthread_exit函数

功能:线程终止
原型
void pthread_exit(void *value_ptr);
参数
value_ptr:value_ptr不要指向一个局部变量。
返回值:无返回值,跟进程一样,线程结束的时候无法返回到它的调用者(自身)

需要注意,pthread_exit或者return返回的指针所指向的内存单元必须是全局的或者是用malloc分配的,不能在线程函
数的栈上分配,因为当其它线程得到这个返回指针时线程函数已经退出了。

#include
#include
#include
#include
#include
using namespace std;
void *thread_runing(void*rid){
int i=0;
while(1){
//int a=9;
//a/=0;
if(i==3){
break;
}
sleep(1);
i++;
cout<<"I am "<<(char*)rid<<endl;
}
return (void*)10;
exit(10);
}
int main(){
pthread_t tid;
pthread_create(&tid,NULL,thread_runing,(void*)"thread 1");
while(1){

cout<<"I am main thread"<<endl;
//sleep(2);
break;
}
void *ret=NULL;
pthread_join(tid,&ret);
cout<<"thread 1 quit code"<<(long long)ret<<endl;
return 0;

}

【校招 --阶段一 系统编程】线程控制_第1张图片

在这里插入图片描述

线程1退出时,将这个返回值数字写入到线程控制块的退出码中.当一个线程异常时(除0错误),系统将无法获取他的退出码。
【校招 --阶段一 系统编程】线程控制_第2张图片
exit(10)终止进程,10为进程退出码。

#include
#include
#include
#include
#include
using namespace std;
void *thread_runing(void*rid){
int i=0;
while(1){

if(i==3){
break;
}
sleep(1);
i++;
cout<<"I am "<<(char*)rid<<endl;
}
pthread_exit((void*)10);
}
int main(){
pthread_t tid;
pthread_create(&tid,NULL,thread_runing,(void*)"thread 1");
while(1){

cout<<"I am main thread"<<endl;
//sleep(2);
break;
}
void *ret=NULL;
pthread_join(tid,&ret);
cout<<"thread 1 quit code"<<(long long)ret<<endl;
return 0;

}

【校招 --阶段一 系统编程】线程控制_第3张图片

2 线程取消

pthread_cancel函数

功能:取消一个执行中的线程
原型
int pthread_cancel(pthread_t thread);
参数
thread:线程ID
返回值:成功返回0;失败返回错误码

#include
#include
#include
#include
#include
using namespace std;
void *thread_runing(void*rid){
int i=0;
while(1){
int a=9;
//a/=0;
//if(i==3){
//break;
//}
sleep(1);
i++;
cout<<"I am "<<(char*)rid<<endl;
}
//return (void*)10;
//exit(10);
//pthread_exit((void*)10);
}
int main(){
pthread_t tid;
pthread_create(&tid,NULL,thread_runing,(void*)"thread 1");
while(1){

cout<<"I am main thread"<<endl;
sleep(4);
pthread_cancel(tid);
break;
}
void *ret=NULL;
pthread_join(tid,&ret);
cout<<"thread 1 quit code"<<(long long)ret<<endl;
return 0;

}

【校招 --阶段一 系统编程】线程控制_第4张图片

线程1退出码为-1

3 线程等待

为什么需要线程等待?
已经退出的线程,其空间没有被释放,仍然在进程的地址空间内。
创建新的线程不会复用刚才退出线程的地址空间

功能:等待线程结束
原型
int pthread_join(pthread_t thread, void **value_ptr);
参数
thread:线程ID
value_ptr:它指向一个指针,后者指向线程的返回值
返回值:成功返回0;失败返回错误码

调用该函数的线程将挂起等待,直到id为thread的线程终止。thread线程以不同的方法终止,通过pthread_join得到的
终止状态是不同的,总结如下:

  1. 如果thread线程通过return返回,value_ ptr所指向的单元里存放的是thread线程函数的返回值。
  2. 如果thread线程被别的线程调用pthread_ cancel异常终掉,value_ ptr所指向的单元里存放的是常数
    PTHREAD_ CANCELED。
  3. 如果thread线程是自己调用pthread_exit终止的,value_ptr所指向的单元存放的是传给pthread_exit的参数。
  4. 如果对thread线程的终止状态不感兴趣,可以传NULL给value_ ptr参数。

4 线程分离

默认情况下,新创建的线程是joinable的,线程退出后,需要对其进行pthread_join操作,否则无法释放
资源,从而造成系统泄漏。
如果不关心线程的返回值,join是一种负担,这个时候,我们可以告诉系统,当线程退出时,自动释放线
程资源。

int pthread_detach(pthread_t thread);

可以是线程组内其他线程对目标线程进行分离,也可以是线程自己分离:

pthread_detach(pthread_self());

	#include
	#include
	#include
	#include
	#include
	using namespace std;
	void *thread_runing(void*rid){
	int i=0;
	while(1){
	pthread_detach(pthread_self());
	sleep(1);
	cout<<"I am "<<(char*)rid<<endl;
	break;
	}
	return (void*)10;
	
	}
	int main(){
	pthread_t tid;
	pthread_create(&tid,NULL,thread_runing,(void*)"thread 1");
	while(1){
	
	cout<<"I am main thread"<<endl;
	sleep(4);
	break;
	}
	void *ret=NULL;
	pthread_join(tid,&ret);
	cout<<"thread 1 quit code"<<(long long)ret<<endl;
	return 0;
	
	}

【校招 --阶段一 系统编程】线程控制_第5张图片

输出的退出码显示为0这是因为主线程拿不到线程1的退出码了,线程1自己释放自己

#include
#include
#include
#include
#include
#include
#include
using namespace std;
int a=10;

void *thread_runing(void*rid){
int i=0;
while(1){
//pthread_detach(pthread_self());
//int a=9;
//a/=0;
//if(i==3){
//break;
//pthread_cancel(pthread_self());
//}
sleep(1);

cout<<"I am "<<(char*)rid<<" pid:"<<getpid()<<"a address "<<&a<<" a:"<<a<<endl;
cout<<"I am "<<(char*)rid<<endl;
}
return (void*)10;
//exit(10);
//pthread_exit((void*)10);
}
int main(){
pthread_t tid;
pthread_t tid1;
pthread_create(&tid,NULL,thread_runing,(void*)"thread 1");
pthread_create(&tid1,NULL,thread_runing,(void*)"thread 2");
//while(1){

cout<<"I am man thread"<<" pid:"<<getpid()<<"a address "<<&a<<" a:"<<a<<endl;
cout<<"I am main thread"<<endl;
cout<<"before a:"<<a<<endl;
sleep(10);
a=100;

cout<<"after a:"<<a<<endl;
//pthread_cancel(tid);
//break;
//}
void *ret=NULL;
pthread_join(tid,&ret);
cout<<"thread 1 quit code"<<(long long)ret<<endl;
void *ret1=NULL;
pthread_join(tid1,&ret1);
cout<<"thread 2 quit code"<<(long long)ret1<<endl;
return 0;

}

【校招 --阶段一 系统编程】线程控制_第6张图片
可以看出函数thread_runing被两个执行流重复进入,该函数被重入了。
被多个执行流访问的资源叫做临界资源。

你可能感兴趣的:(校招,linux,Linux,文件系统,静态库,线程控制)