本文提到线程池加速:线程池给你写好了,想加速拿来用就行哈
备注:上文链接1已经被应用在某学弟学妹论文中,故已删除!
这两天小伙伴反应看了之后还是不会写多线程。于是,趁着周末大致梳理下多线程的知识巴拉。
1.无参可执行体:
#include<iostream>
#include<thread>
using namespace std;
void fun1() {
cout << "fun1" << endl;
}
void fun2() {
cout << "fun2" << endl;
}
int main() {
thread th1 = thread(fun1);
thread th2 = thread(fun2);
//join等待线程完成,一个线程等待另外一个线程
th1.join();
th2.join();
}
2.类可执行体
#include<iostream>
#include<thread>
using namespace std;
class MaLu {
public:
void operator()() {
//重载了括号
cout << "重载运算符" << endl;
}
};
int main() {
MaLu malu;
thread th = thread(malu);
th.join();
}
3.lambda表达式
#include<iostream>
#include<thread>
using namespace std;
int main() {
thread th = thread([](){
cout << "lmbda参数" << endl;
});
th.join();
}
4.带参执行体
#include<iostream>
#include<thread>
using namespace std;
void func(int n) {
cout << n << endl;
}
int main() {
thread th(func, 100);
th.join();
}
5.返回值执行体
#include<iostream>
#include<thread>
#include<future>
#include<ctime>
using namespace std;
int sum(int n) {
int ret = 0;
for (int i = 1; i <= n; i++) {
ret += i;
}
return ret;
}
int main() {
clock_t start,end1;
future<int> f = async(sum, 100);
cout << f.get() << endl;
end1=clock();
double endtime=(double)(end1-start)/CLOCKS_PER_SEC;
cout<<"Total time:"<<endtime<<endl; //s
}
6.多线程求和
#include<iostream>
#include<thread>
#include<future>
#include<ctime>
using namespace std;
clock_t start,end1;
int sum(int start, int end) {
int ret = 0;
for (int i = start; i <= end; i++) {
ret += i;
}
return ret;
}
int main() {
int n=100;
start=clock();
future<int> s1 = async(sum, 1, n / 2);
future<int> s2 = async(sum, n / 2 + 1, n);
cout << (s1.get() + s2.get()) << endl;
end1=clock();
double endtime=(double)(end1-start)/CLOCKS_PER_SEC;
cout<<"Total time:"<<endtime<<endl; //s
}
7.借助互斥锁
#include<iostream>
#include<thread>
#include<mutex>
std::mutex mtx;
using namespace std;
//让某一段代码在同一时刻只有一个线程在执行,就需要借助互斥锁
int n = 0;
void fun() {
mtx.lock();
n*=3;
mtx.unlock();
}
int main() {
thread th1 = thread(fun);
//join等待线程完成
th1.join();
}
8.来个信号量
#include<thread>
#include<iostream>
#include<condition_variable>
using namespace std;
//条件变量必须和mutex互斥量结合,先要用mutex进行初始化条件变量方可使用。
mutex mtx;
condition_variable cv;
bool ready = false;
//条件变量而言,则是一个或者多个线程等待一个线程的信号。这是join和条件变量的最明显的区别
void run(int id) {
unique_lock<mutex> lock(mtx);
while (!ready)
cv.wait(lock);
cout << "选手" << id << "跑了" << endl;
}
int main() {
thread th[5];
for (int i = 0; i < 5; i++) {
th[i] = thread(run, i);
}
ready = true;
cv.notify_all();
for (auto& t : th) {
t.join();
}
}
9.应用在图像上
#include <pthread.h>
#include <opencv2/opencv.hpp>
using namespace cv;
int* hhnum; Mat img;
int threadnums = 4;
void* jia(void*params)
{
int args = *(int*)params;
free(params);
while (true)
{
img = imread("result.jpg");
*hhnum =args;
std::cout << *hhnum << std::endl;
imwrite("4.jpg", img);
}
}
int main()
{
hhnum = new int[1];
pthread_t *threads = (pthread_t*)calloc(threadnums, sizeof(pthread_t));
for (size_t i = 0; i < threadnums; i++)
{
int*ptr = (int*)calloc(1, sizeof(int));
*ptr = i;
pthread_t thread;
pthread_create(&thread, 0, jia, ptr);
threads[i] = thread;
}
for (size_t j = 0; j < threadnums; j++)
{
try
{
pthread_join(threads[j], 0); //这个创建的线程是阻塞式的,只有当所有的线程结束后,程序才会往下执行。
}
catch (Exception e)
{
int i = 0;
}
}
}
10.遇到for就omp
#include <pthread.h>
#include <opencv2/opencv.hpp>
#include <chrono>
using namespace cv;
using namespace std;
int main()
{
Mat imgg = imread("result.jpg");
for (size_t i = 0; i < 90; i++)
{
//openomp实现格式#pragma omp 指令...; parallel表示这段代码将被多个线程并行执行。
//num_threads 指定并行域内的线程的数目。
#pragma omp parallel num_threads(4)
{
//用来取消栅障。其栅障是用于线程同步的一种方法,线程遇到栅障时必须等待,知道并行的所有的线程都到达同一个点。
#pragma omp for nowait
for (int32_t i = 0; i < 1; i++)
{
for (int32_t j = 0; j < imgg.cols; j++)
{
imgg.at<Vec3b>(i, j)[0] = imgg.at<Vec3b>(i, j)[0] * 0.01;
imgg.at<Vec3b>(i, j)[1] = imgg.at<Vec3b>(i, j)[1] * 0.01;
imgg.at<Vec3b>(i, j)[2] = imgg.at<Vec3b>(i, j)[2] * 0.01;
}
}
}
}
}