21.C++多线程以及C++11多线程操作

本文介绍了C++11中的多线程编程,包括线程的创建、终止、实例,以及C++11标准库std::thread的使用,如构造、析构函数、成员函数、future、promise等,并探讨了线程同步机制mutex和atomic。

多线程

多线程是多任务处理的一种特殊形式,多任务处理允许让电脑同时运行两个或两个以上的程序。
多任务处理分为两种类型:基于进程和基于线程

  • 基于进程的多任务处理是程序的并发执行
  • 基于线程的多任务处理是同一程序的片段并发执行
    假设您使用的是 Linux 操作系统,我们要使用 POSIX 编写多线程 C++ 程序。POSIX Threads 或 Pthreads 提供的 API 可在多种类 Unix POSIX 系统上可用,比如 FreeBSD、NetBSD、GNU/Linux、Mac OS X 和 Solaris。

线程的创建

创建POSIX线程

#include <pthread.h>
pthread_create(thread,attr,start_routine,arg);

在这里,pthread_create 创建一个新的线程,并让它可执行。下面是关于参数的说明:

  • thread:是一个指向线程标识符的指针
  • attr:用来被设置线程属性,可以指定,也可以默认NULL
  • start_rountine:线程运行的起始地址,一旦线程被创建就会被执行
  • arg:运行函数的参数,它必需通过把引用作为指针强制转换为 void 类型进行传递。没有传参就使用NULL。

线程的终止

#include<pthread.h>
pthread_exit(status)

pthread_exit 用于显式地退出一个线程。通常情况下,pthread_exit() 函数是在线程完成工作后无需继续存在时被调用。

如果main函数创建了一个线程,线程如果还没运行完main就退出了。如果通过pthread_exit()退出的,线程继续执行,否则main()结束线程也随之结束。

多线程实例1

用pthread_create()函数创建5个线程,每个线程都输出一段字符串;
要点:

  1. create线程的第一个参数是一个地址要:&
  2. 线程得先终止
#include<iostream>
#include<pthread.h>
using namespace std;
#define numofthread 5

//线程的运行函数
void* say_hello(void* args)
{
   
   
  cout << "Hello Nowcoder!" << endl;
    return 0;
}

int main()
{
   
   
	//定义线程的ID,多使用数组来存储
	pthread_t tids[numofthread];
	for(int i=0;i<numofthread;++i)
	{
   
   
	int ret=pthread_create(&tids[i],NULL,say_hello,NULL);//参数依次为:创建线程的id地址,线程参数,线程调用的函数,传入的函数参数(注意这里用int接收是因为say_hello这个函数要返回0才运行成功)
	if(ret!=0)//说明发生异常,线程创建不成功
	{
   
   
		cout<<"thread create error,error code="<<ret<<endl;
	}
	}
	pthread_exit(NULL);//各个线程退出之后,main这个进程才结束,否则main如果提前结束了线程可能没有反应过来。
	
}

使用 -lpthread 库编译下面的程序:

$ g++ test.cpp -lpthread -o test.o

现在,执行程序,将产生下列结果:

$ ./test.o
Hello Nowcoder!
Hello Nowcoder!
Hello Nowcoder!
Hello Nowcoder!
Hello Nowcoder!

多线程实例2:线程接收传入参数并输出参数

以下简单的实例代码使用 pthread_create() 函数创建了 5 个线程,并接收传入的参数:数组的地址。每个线程打印一个 “Hello Nowcoder!” 消息,并输出接收的参数,然后调用 pthread_exit() 终止线程。

要点:

  1. 线程运行函数的参数一定要强制转化为(void*
  2. 而后在运行函数内,将其再次强制转化为可使用的类型
//文件名:test.cpp
 
#include <iostream>
#include <cstdlib>
#include <pthread.h>
 
using namespace std;
 
#define NUM_THREADS     5

void* printhello(void* threadID)
{
   
   
	//因为传入的参数是无类型指针,所以我们需要对其进行强制类型转换,为整数型指针,然后再读取
	int tid=*((int*)threadID);
	cout<<"Hello Nowcoder! 线程 ID, " << tid << endl;
	//终止线程
	pthread_exit(NULL);
}

int main()
{
   
   
pthread_t thread[NUM_THREADS];
int indexes[NUM_THREADS];//用数组保存整数型id
int rc,i;
for(i=0;i<NUM_THREADS;++i)
{
   
   
	cout<<"main创建线程  "<<i<<endl;
	indexes[i]=i;
	//传入的时候必须强制转换为void* 类型,即无类型指针 ,原始类型是每个id的地址&indexes[i]
	rc=pthread_create(&thread[i],NULL,printhello,(void*)&(indexes[i]));
	//注意调用函数正常运行直接终止线程,不会返回数值给rc,也就是说正常情况下rc一直是默认0,如果非0代表异常
	if(rc)
	{
   
   
		cout << "Error:无法创建线程," << rc << endl;
         exit(-1);
}
pthread_exit(NULL);

}

执行:

$ g++ test.cpp -lpthread -o test.o
$ ./test.o
main() : 创建线程, 0
main() : 创建线程, 1
Hello Nowcoder! 线程 ID, 0
main() : 创建线程, 3
Hello Nowcoder! 线程 ID, 2
main() : 创建线程, 4
Hello Nowcoder! 线程 ID, 3
Hello Nowcoder
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值