线程标识和创建 Linux_C/C++

14 篇文章 0 订阅
9 篇文章 0 订阅

线程标识和创建

线程标识

进程ID在整个系统中是唯一的,但线程ID只在它所属的进程环境中有效。

线程ID用pthread_t数据类型表示,所以可移植的操作系统实现不能把它作为整数来处理,因此必须使用函数来对两个线程ID进行比较

int pthread_equal(pthread_t tid1, pthread_t tid2);
//参数:两个线程的线程ID
//返回值:相等则返回非0值,否则返回0

线程也可以通过调用pthread_self函数获得自身线程ID

pthread_t pthread_self(void);
//返回值:调用线程的线程ID

当线程需要识别以线程ID作为标识的数据结构时,pthread_self函数可以与pthread_equal函数一起使用。

应用:比如:主线程可能把工作任务放在一个队列中,用线程ID来控制每个工作线程处理哪些作业,每个线程并不是任地处理从队列顶端取出的作业,每个工作线程只能移出标有自己线程ID的作业。

线程创建

可以使用pthread_create函数创建新线程。

int pthread_create(
    pthread_t *thread, 		//返回线程ID
    const pthread_attr_t *attr,	//设置线程的属性,NULL为默认属性
    void *(*start_routine)(void*),	//县城启动后要执行的函数
    void *arg);	//传给线程启动函数的参数
//返回值:成功返回0,失败返回错误码

注意:

  • pthread_create函数成功返回时,由thread指向的内存单元被设置为新创建线程的线程ID。
  • 新创建的线程从start_routine函数的地址开始运行,该函数只有一个无类型指针arg,如果需要向start_routine函数传递的参数不止一个,那么需要把这些参数放到一个结构体中,然后把这个结构的地址作为arg参数传入。
  • 线程创建时并不能保证哪个函数会先运行,不管是主线程还是新创建的线程。

pthread_create和pthread_self的用法:

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

void* route(void*){
	printf("I am new thread...\n");
	pthread_t tid = pthread_self(); //通过pthread_self获得线程tid
	printf("my tid is %ld\n", tid);
	return NULL;
}
int main(){
	pthread_t tid;
	int ret = pthread_create(&tid, NULL, route, NULL);
    			//新线程的线程ID在tid中,属性为NULL,要执行的函数为route,其函数参数为NULL;
	if(ret != 0){
		printf("create error...\n");
		return 0;
	}
	sleep(1);	//让主线程休眠一秒钟,sleep函数的头文件是unistd.h
	return 0;
}

在这里插入图片描述
例子:

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

void print(const char* s){  //打印调用该函数的线程的pid和tid
	pid_t pid;
	pthread_t tid;
	pid = getpid();
	tid = pthread_self();
	cout << s << " pid " << pid;
	cout << " tid " << dec << tid << " ";	//以十进制输出tid
	cout << "(0x" << hex << tid << ")" << endl;	//以十六进制输出tid
	return NULL;
}
void* route(void* ){
	print("new thread: ");
	return NULL;
}
int main(){

	int ret;
	pthread_t tid;
	ret = pthread_create(&tid, NULL, route, NULL);
	if(ret != 0){
		cout << "create error..." << endl;
	}
	print("main thread: ");
	sleep(1);
	return 0;
}

在这里插入图片描述
注意:

  • 创建新线程后,要处理主线程和新线程的竞争关系。主线程需要休眠,如果主线程不休眠就有可能退出,这样可能新线程还没开始运行,整个进程就终止了。
  • 获取线程ID时最好通过调用pthread_self函数获取,而不是从共享内存中读出或从线程的启动例程中以参数的形式读到。因为pthread_create函数会通过第一个参数thread返回新建线程的线程ID,但新建的线程并不能安全的使用,如果新线程在主线程调用pthread_create返回之前就运行了,那么新线程看到的是未经初始化的thread内容,这个并不是正确的线程ID。
  • C++中cout << hex << n, cout << oct << n, cout << dec << n分别是将整数n以十六进制、八进制和十进制的形式输出。
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值