Linux多线程编程之pthread


头文件:#include <pthread.h>
在编译时注意加上-lpthread参数,以调用静态链接库。因为pthread并非Linux系统的默认库。

1.线程创建

函数声明

int pthread_create(pthread_t * thread, const pthread_arrt_t* attr,void*(*start_routine)(void *), void* arg);

-thread:指向线程标识符的指针
-attr:线程的属性。给传递NULL表示设置为默认线程属性
-start_routine:线程执行实体入口
arg:运行函数的参数
-返回值:成功返回0,失败返回错误码
-typedef unsigned long int pthread_t

线程id的类型是pthread_t,它只在当前进程中保证是唯一的,在不同的系统中pthread_t这个类型有不同的实现,调用pthread_self()可以获得当前线程的id.

代码演示:

#include<stdio.h>
#include<pthread.h>
#include<stdlib.h>
#include<errno.h>
#include<unistd.h>

void* thread_start(void* arg){
	
	int arg_data = *((int*)arg);
	for (int i = 0; i < 10; i++){
		//这里要注意一下
		//当创建一个线程之后,该线程和主线程一起执行,若主线程提前退出了,thread_start这个线程还没有来得及打印也会因为主线程退出而退出了
		for (int j = 0; j < 5000000; j++);
		printf("Receive arg %d=%d\n", arg_data, arg_data);
	}
}
int main(void){

	pthread_t tid ;
	int arg1 = 1;
	int arg2 = 2;
	//创建线程
	int ret = pthread_create(&tid, NULL, thread_start, (void*)&arg1);
	if (ret != 0){
		printf("Create pthread error!\n");
		exit(EXIT_FAILURE);
	}
    //	sleep(10);
	thread_start((void*)&arg2);
	return 0;
}

运行结果:
在这里插入图片描述

2. 线程等待

函数声明:

void pthread_join(pthread_t thread,void ** retval);

-thread:线程标识符
-retval:用户定义的指针,用来存储被等待线程的返回值。
-如果执行成功,将返回0,如果失败则返回一个错误码。

在这里插入图片描述
代码演示:

#include<stdio.h>
#include<pthread.h>
#include<stdlib.h>
#include<errno.h>
#include<unistd.h>

void *thread_start(void *arg){

	int i = 0;
	for (i = 0; i < 8; i++){

		printf("Thread working...! %d \n", i);
		sleep(1);
	}
	char* p;
	p= "hello";
	pthread_exit(p);
}

int main(){

	pthread_t tid;
	int ret = pthread_create(&tid, NULL, thread_start, NULL);
	if (ret != 0){
		printf("Create pthread error!\n");
		exit(EXIT_FAILURE);
	}
	void* ans;
	int jret = pthread_join(tid, &ans);
	if (jret != 0){
		printf("Join pthread error!\n");
		exit(EXIT_FAILURE);
	}
	printf("thread return %s\n", (char*)ans);
	printf("thread done! \n");
	return 0;
}

3.线程分离

函数说明:

即主线程与子线程分离,子线程结束后,资源自动回收。

函数声明:

int pthread_detach(pthread_t tid);

-tid:线程标识符
-返回值:成功返回0,失败返回错误码

线程资源回收

1.linux线程执行和windows不同,pthread有两种状态joinable状态和unjoinable状态,如果线程是joinable状态,当线程函数自己返回退出时或pthread_exit时都不会释放线程所占用堆栈和线程描述符。只有当你调用了pthread_join之后这些资源才会被释放。若是unjoinable状态的线程,这些资源在线程函数退出时或pthread_exit时自动会被释放。
2.unjoinable属性可以在pthread_create时指定,或在线程创建后在线程中pthread_detach自己, 如:pthread_detach(pthread_self()),将状态改为unjoinable状态,确保资源的释放。或者将线程置为 joinable,然后适时调用pthread_join.
3.其实简单的说就是在线程函数头加上 pthread_detach(pthread_self())的话,线程状态改变,在函数尾部直接 pthread_exit线程就会自动退出。省去了给线程擦屁股的麻烦。
代码演示:

 pthread_t tid;
 int status = pthread_create(&tid, NULL, ThreadFunc, NULL);
 if(status != 0)
 {
  perror("pthread_create error");
 }
 pthread_detach(tid);

4.线程的终止

终止线程的三种方式:
-从start_routine正常return
-显示调用pthread_exit(),终止自己
-线程被pthread_cancel()取消

pthread_exit()函数

函数声明:

void pthread_exit(void * retval);

-retval:指向线程占用资源的指针。由于一个进程中的多个线程是共享数据段的,因此通常在线程退出之后,退出线程所占用的资源并不会随着线程的终止而得到释放。其它线程可以调用pthread_join获得这个指针。
代码演示:

#include<stdio.h>
#include<pthread.h>
#include<stdlib.h>
#include<errno.h>
#include<unistd.h>

void* thread_start(void* arg){

	int arg_data = *((int*)arg);
	for (int i = 0; i < 10; i++){
		//这里要注意一下
		//当创建一个线程之后,该线程和主线程一起执行,若主线程提前退出了,thread_start这个线程还没有来得及打印也会因为主线程退出而退出了
		for (int j = 0; j < 5000000; j++);
		printf("Receive arg %d=%d\n", arg_data, arg_data);
		pthread_exit(NULL);
	}
}
int main(void){

	pthread_t tid;
	int arg1 = 1;
	int arg2 = 2;
	//创建线程
	int ret = pthread_create(&tid, NULL, thread_start, (void*)&arg1);
	if (ret != 0){
		printf("Create pthread error!\n");
		exit(EXIT_FAILURE);
	}
	thread_start((void*)&arg2);
	return 0;
}

运行结果:
在这里插入图片描述

pthread_cancel()函数

函数声明:

int pthread_cancel(pthread_t thread);

-thread:目标线程的标识符。
-成功返回0,失败返回错误码。

代码演示:

#include<stdio.h>
#include<pthread.h>
#include<stdlib.h>
#include<errno.h>
#include<unistd.h>

int sum = 0;
void* thread_start(void* arg){
	int i;
	int len = *(int *)arg;
	for (int i = 0; i < len; i++){
		sum = i;
		sleep(1);
		printf("sub thread:sum=%d\n", sum);
	}
	printf("sub thread:exit\n");
	//pthread_exit(NULL);
}
int main(){
	pthread_t tid;
	int arg = 10;
	pthread_create(&tid, NULL, thread_start, (void*)&arg);
	sleep(5);
	pthread_cancel(tid);
	printf("main thread:sum=%d\n", sum);
	printf("main thread exit\n");
	return 0;
}

运行结果:
在这里插入图片描述

发布了87 篇原创文章 · 获赞 73 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/HL_HLHL/article/details/104827704