小伙伴们在刚接触程序的时候呢,知道程序是按顺序一步一步向下进行的,可能你知道一个函数执行完,再去执行另一个函数。那如何在一段时间内,“同时”执行几个函数呢,让它们同时进行呢,这里的同时是带引号的,在一个cpu的情况下,任何计算都是需要时间的,只是他们分别占用了很少的时间段,让你感觉上是同时进行的。
简单的理解就是我们看到日常的灯,是通过交流电,当它亮的时候,不是一直亮着的,而是一闪一闪的,肉眼是看不出来的。好了说了这样多我们来看看吧。
函数指针创建线程
包含头文件:
#include <iostream>
#include <thread>
using namespace std;
void counter(int id, int numIterations)
{
for (int i = 0; i<numIterations; ++i)
{
cout << "Counter" << id << "has value";
cout << i << endl;
}
}
void testThreadC()
{
thread t1(counter,1,6);
thread t2(counter,2,4);
t1.join();
t2.join();
}
没错就是这样简单,同过thread 定义一个变量,第一个参数是自己定义的函数,后面是你函数对应的参数。通过join,就启动了你的线程了 ,它不会执t1中的函数后在执行t2中的函数,而是“同时进行”:
结果1:
Counter1has value0Counter2has value0
Counter1Counter2has value1has value1
Counter1Counter2has value2has value2
Counter1Counter2has value3has value3
Counter1has value4
Counter1has value5
结果2:
CounterCounter2has value01has value0
Counter1Counter2has value1has value1
Counter1has value2
Counter2has value2Counter1has value3
Counter2has value3Counter1
has value4
Counter1has value5
同过上面的执行了两次,每次执行的都不一样,而且非常的乱并不是相互完成执行,就导致了这个样子达不到目标期望。
后面会讲到同步方法来修正它,请不要着急。
函数对象创建线程
class Counter
{
public:
Counter(int id, int numIterations)
:mId(id), mNumIterations(numIterations)
{
}
void operator ()() const
{
for (int i = 0; i < mNumIterations; ++i)
{
cout << "Counter " << mId << " has value ";
cout << i << endl;
}
}
private:
int mId;
int mNumIterations;
};
void testCounter()
{
//using uniform initialization syntax
thread t1{ Counter{1,20} };
//using named variable
Counter c(2,12);
thread t2(c);
//using temporary
thread t3(Counter(3,10));
//wait for threads to finish
t1.join();
t2.join();
t3.join();
}
对象的方法来写入,有三种方式,第一种{} 形式,与第三种() 的形式,建议统一使用第一种,当使用第三种的使用,当你的Counter 没有参数的话直接写:
thread t3(Counter());
这样是会报错的,Counter()返回的一个thread对象,其参数是指针,它指向返回一个Counter对象的无参数函数。
输出结果:
Counter Counter 2 has value 0
Counter 3 has value 0
Counter 3 has value 1
Counter 21 has value 0 has value 1
Counter 3
has value 2
Counter 1 has value 1
Counter 2 has value 2Counter 1Counter 3
has value 3
Counter 2 has value 2
Counter 3 has value 3
Counter 1 has value 4
Counter 2 has value 3
Counter 3 has value 4
Counter 1 has value 5
has value 4
Counter 1Counter 3 has value 6Counter 2 has value 5
has value 5
Counter 3 has value 7Counter 1 has value 6Counter 2
has value 6
Counter 3
has value 8
Counter 1 has value 7
Counter 2 has value 7Counter 3 has value 9Counter 1
has value 8
Counter 1 has value 9Counter 2
Counter 1 has value 10
has value 8
Counter 1 has value 11
Counter 1 has value 12
Counter 2 has value 9
Counter 1 has value 13
Counter 1 has value 14
Counter Counter 2 has value 10
1 has value 15
Counter 2 has value 11
Counter 1 has value 16
Counter 1 has value 17
Counter 1 has value 18
Counter 1 has value 19
同样的也会非常乱,同样后面会有讲解解方案。
lambda 对象创建线程
void testLambda()
{
int id = 1;
int id2 = 2;
int numIterations = 5;
thread t1( [id, numIterations] {
for (int i = 0; i < numIterations; ++i)
{
cout << "Counter " << id << " has value ";
cout << i << endl;
}
});
thread t2([id2, numIterations] {
for (int i = 0; i < numIterations; ++i)
{
cout << "Counter " << id2 << " has value ";
cout << i << endl;
}
});
t1.join();
t2.join();
}
测试结果:
Counter Counter 2 has value 01
has value 0
Counter 2 has value 1Counter 1
has value 1
Counter 2 has value 2Counter 1
has value 2
Counter 2 has value 3Counter 1 has value 3
Counter 2Counter 1 has value 4 has value 4
依旧朴实无华,且非常的乱,别急呀,这篇主要讲解几种创建的方法,问题会解决的,关注博客不迷路。
成员函数创建线程:
class Request
{
public:
Request(int id) :mId(id){}
void process()
{
cout << "Process request " << mId << endl;
}
private:
int mId;
};
void testRequest()
{
Request req(100);
thread t{&Request::process, &req };
t.join();
}
测试结果:
Process request 100
使用这个也会变得非常乱,对于多线程对输出与输入在同一个对象上的话,必须要加互斥量。