多线程
多线程是多任务处理的一种特殊形式,多任务处理允许让电脑同时运行两个或两个以上的程序。
多任务处理分为两种类型:基于进程和基于线程
- 基于进程的多任务处理是程序的并发执行。
- 基于线程的多任务处理是同一程序的片段并发执行
假设您使用的是 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个线程,每个线程都输出一段字符串;
要点:
- create线程的第一个参数是一个地址要:&
- 线程得先终止
#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() 终止线程。
要点:
- 线程运行函数的参数一定要强制转化为(void)*
- 而后在运行函数内,将其再次强制转化为可使用的类型
//文件名: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

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

被折叠的 条评论
为什么被折叠?



