Linux 多线程

1.创建线程 -- pthread

表头文件

 #include <pthread.h>

定义函数

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

函数说明

参数:

thread: 传出参数,线程创建成功后会被设置一个合适的值,线程ID(无符号长整形);

attr:线程属性,默认传NULL;(通过属性设置线程分离:见补充1)

start_routine:线程处理函数

arg:线程处理回调函数的参数

返回值

调用成功新线程的指针会被存储到thread的参数中,并返回0,失败返回错误号;

如果返回EAGAIN,没有足够的系统资源创建一个线程,或者已经存在大于PTHREAD_THREADS_MAX个活跃线程。

#include <iostream>
#include<pthread.h>
#include<unistd.h>
using namespace std;

void* myfunc(void*) {
	//打印子线程的id
	cout << "Child thread id : "<< pthread_self() << endl;
	return NULL;
}

int main(int argc,const char* argv[])
{
	//创建一个子线程
	//线程id变量
	pthread_t pthid;
	pthread_create(&pthid, NULL, myfunc, NULL);
	//打印父线程的id
	cout << "parent thread id :" << pthread_self()<<endl;
	for (int i = 0; i < 5; ++i) {
		cout << "i=" << i<<endl;
	}
	sleep(2);
    return 0;
}

parent thread id :140737354053440
i=0
i=1
i=2
i=3
i=4
Child thread id : 140737337173760

 打印错误信息:

	pthread_t pthid;
	int ret = pthread_create(&pthid, NULL, myfunc, NULL);
	if (ret != 0) {
		cout << "error number: " << ret<<endl;
		//打印错误信息
		cout<<strerror(ret)<<endl;   //#include<string.h>
	}

2.单个线程退出 -- pthread_exit

表头文件

 #include <pthread.h>

定义函数

 void pthread_exit(void *retval);

函数说明

pthread_exit结束调用线程的执行.所有通过pthread_cleanup_push设置的清除句柄将会被反序执行(后进先出)。 所以key值非空的线程特定数据Finalization functions被调用(参见pthread_key_create) 最后调用线程被终止。

retval是这个线程结束的返回值,可以通过在别的线程中调用pthread_join来获取这个值。(retval必须指向全局或者堆

返回值

没有返回值

3. 阻塞函数等待线程退出,获取线程退出状态 -- pthread_jion

表头文件

 #include <pthread.h>

定义函数

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

函数说明

thread:要回收子线程的线程id

retval:读出线程退出的时候携带的状态信息

用法:

void* ptr;

pthread_join(pthid,&ptr);

ptr 指向内存和pthead_exit参数指向同一块内存地址

返回值

  如果成功,返回值存储在thread_return中,并返回0,否则返回错误码:
   ESRCH:找不到指定线程
   EINVAL:线程th是detached或者已经存在另一个线程在等待线程th结束
   EDEADLK:th的参数引用它自己(即线程不能join自身)

#include <iostream>
#include<pthread.h>
#include<unistd.h>
#include<string.h>
using namespace std;

void* myfunc(void* arg) {
	//打印子线程的id
	cout << "child thread id : "<< pthread_self() << endl;
	for (int i = 0; i < 5; ++i) {
		cout << "child i=" << i << endl;
		if (i == 2) {
			int *pret;
			pret = new int;
			*pret = 10;
			//子线程退出
			pthread_exit(pret);
		}
	}

	return NULL;
}

int main(int argc,const char* argv[])
{
	//创建一个子线程
	//线程id变量
	pthread_t pthid;
	int ret = pthread_create(&pthid, NULL, myfunc, NULL);
	if (ret != 0) {
		cout << "error number: " << ret<<endl;
		//打印错误信息
		cout<<strerror(ret)<<endl;
	}
	//打印父线程的id
	cout << "parent thread id :" << pthread_self()<<endl;

	//阻塞等待子线程退出,并且回收pcb
	void* ptr;
	pthread_join(pthid,&ptr);
	cout << "ptr = "<<*(int*)ptr << endl;
	delete (int* )ptr;
	for (int i = 0; i < 5; ++i) {
		cout << "parent i=" << i<<endl;
	}
    return 0;
}

4.线程分离 -- pthread_detach

表头文件

 #include <pthread.h>

定义函数

 int pthread_detach(pthread_t thread);

函数说明

调用该函数之后不需要pthread_join

设置分离后子线程会自己回收自己的PCB

返回值

 

5.取消线程 -- pthread_cancel

表头文件

 #include <pthread.h>

定义函数

 int pthread_cancel(pthread_t thread);

函数说明

在要杀死的子线程对应的处理的函数的内部,必须做过一次系统调用。

返回值

 

6.比较两个线程ID是否相等(预留函数)-- pthread_equal

表头文件

 #include <pthread.h>

定义函数

 int pthread_equal(pthread_t thread_1, pthread_t thread_2);

函数说明

 

返回值

 

补充1.通过属性设置线程的分离

1)线程的属性类型:pthread_attr_t attr;

2)线程的属性操作函数:

对线程属性变化量的初始化 -- pthread_attr_init

表头文件

 #include <pthread.h>

定义函数

 int pthread_attr_init(pthread_attr_t *attr);

函数说明

对线程属性变化量的初始化

返回值

 

设置线程分离属性 -- pthread_attr_setdetachstate

表头文件

 #include <pthread.h>

定义函数

int pthread_attr_setdetachstate(pthread_attr_t *attr, int datachstate);

函数说明

设置线程分离属性

datachstate:

  • PTHREAD_CREATE_DETACHED(分离)
  • PTHREAD_CREATE_JOINABLE(非分离)

返回值

 

释放线程资源函数 -- pthread_attr_destroy

表头文件

 #include <pthread.h>

定义函数

int pthread_attr_destroy(pthread_attr_t * attr);

函数说明

释放线程资源函数

返回值

 

#include <iostream>
#include<pthread.h>
#include<unistd.h>
#include<string.h>
using namespace std;

void* myfunc(void* arg) {
	//打印子线程的id
	cout << "child thread id : "<< pthread_self() << endl;
	return NULL;
}

int main(int argc,const char* argv[])
{
	//创建一个子线程
	//线程id变量
	pthread_t pthid;
	
	pthread_attr_t attr;
	pthread_attr_init(&attr);
	pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);

	int ret = pthread_create(&pthid, &attr, myfunc, NULL);
	if (ret != 0) {
		cout << "error number: " << ret<<endl;
		//打印错误信息
		cout<<strerror(ret)<<endl;
	}
	//打印父线程的id
	cout << "parent thread id :" << pthread_self()<<endl;
	
	for (int i = 0; i < 5; ++i) {
		cout << "parent i=" << i<<endl;
	}
	sleep(2);
	pthread_attr_destroy(&attr);
    return 0;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值