c++ 如何获取多线程的返回值?

        使用 原子锁 代替 条件变量
	// c++20
	std::atomic<bool> condition{ false };
	std::cout << "run" << std::endl;
	std::thread run([&cond = condition]() {
		std::cout << "sleep" << std::endl;
		std::this_thread::sleep_for(5s);
		cond = true;
		std::cout << "notify" << std::endl;
		cond.notify_one();
	});
	run.detach();

	std::cout << "wait" << std::endl;
	condition.wait(false);
//简单的 c++11 线程,简单方便,成员函数随便调用,非成员函数也一样,如需要获取返回时,请自行使用条件变量
    std::thread run([&](){
        //执行一些耗时的操作
        return 0;
    });
    run.detach();

继承类方式多线程

#include <thread>
#include <atomic>
#include <iostream>
class Thread {
public:
	~Thread() {
		if (m_thread.joinable()) {
			isInterruptionRequested();
			m_thread.join();
		}
	}
	void statr() {
		if (!m_thread.joinable()) {
			isInterruptionRequested();
			m_thread = std::thread(&Thread::run, this);//开启一个线程
		}
	}
	void requestInterruption() {
		m_requestInterruption.clear(std::memory_order_acquire);//结束循环
	}
	bool isInterruptionRequested() {
		return m_requestInterruption.test_and_set(std::memory_order_acquire);//判断循环是否正在运行
	}
protected:
	virtual void run() {
		while (isInterruptionRequested())
		{
			std::cout << "long task handle" << std::endl;//执行一些耗时的任务
		}
		std::cout << "run end" << std::endl;
	}
private:
	std::thread m_thread;
	std::atomic_flag m_requestInterruption = ATOMIC_FLAG_INIT;
};

原子锁(atomic)-抢占式

#include <iostream>
#include <thread>
#include <atomic>
#include <chrono>
std::atomic_flag flag = ATOMIC_FLAG_INIT;
void process()
{
	//获取锁
	while (flag.test_and_set(std::memory_order_acquire)){
		//休眠 500 毫秒
		//std::this_thread::sleep_for(std::chrono::milliseconds(500));
	}

	/* 线程保护区域(Zone to portect) */
	// Task

	//释放锁
	flag.clear(std::memory_order_release);
}
    auto run=std::async([&](){
        return this->执行一些耗时的操作成员函数();
    });
    run.get();
    auto run=std::async(std::launch::async,[&](){
        return this->执行一些耗时的操作成员函数();
    });
    run.get();
auto future = std::async(std::launch::deferred, function, arg1, arg2);
 
// some time later, possibly in another thread:
future.get(); // calls the function with the arguments
// Console.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include <stdlib.h>
#include <iostream>
#include <thread>	//线程库
#include <future>
#include <mutex>
#include<numeric>

std::mutex g_display_mutex;

void foo()
{
	std::thread::id this_id = std::this_thread::get_id();

	g_display_mutex.lock();
	std::cout << "thread " << this_id << " sleeping...\n";
	g_display_mutex.unlock();

	std::this_thread::sleep_for(std::chrono::seconds(0));
}

void threadTest()
{
	std::thread t1(foo);
	std::thread t2(foo);
	t1.join();
	t2.join();
}

int sum(int &x, int &y)
{
	std::cout << std::hex << std::this_thread::get_id() << std::endl;
	std::this_thread::sleep_for(std::chrono::seconds(1));
	return x + y;
}

int sums(int x, int y,int z)
{
	std::cout << std::hex << std::this_thread::get_id() << std::endl;
	std::this_thread::sleep_for(std::chrono::seconds(1));
	return x + y + z;
}


int main()
{
	
	int x = 3;
	int y = 4;
	std::future<int> fu = std::async(sums, 3, 4,5);
	//std::future<int> fu = std::async(sum,std::ref(x),std::ref(y));
	std::cout << fu.get() << std::endl;

	//获取当前计算机线程数量
	std::cout << std::thread::hardware_concurrency() << std::endl;
	//获取当前线程ID
	std::cout << std::hex <<std::this_thread::get_id() << std::endl;
	system("pause");
    return 0;
}

#include <thread>
#include <memory>
#include <string>
#include <future>
#include <mutex>
#include<numeric>
#include <cstdlib>
#include <iostream>

int main()
{
	std::cout << "start 当前 main 线程ID:" << std::this_thread::get_id() << std::endl;

	// 定义函数原型
	auto fn = [](const char *info)->int {
		int sum = 0;
		for (int i = 0; i < 1000000000; ++i) {
			++sum;
		}
		std::cout << std::string(info) << " 线程ID:" << std::this_thread::get_id() << " sum:" << sum << std::endl;
		return sum;
	};

	// 异步求值
	std::future<int> calc_async = std::async(std::launch::async,fn,"异步求值");

	// 惰性求值
	std::future<int> calc_deferred = std::async(std::launch::deferred,fn,"惰性求值");

	std::cout << "end 当前 main 线程ID:" << std::this_thread::get_id() << std::endl;

	// 启动线程
	std::cout << "惰性求值结果:" << calc_deferred.get() << std::endl;

	/*!
		运行以上代码可以看出,惰性求值 方式需要调用 calc_deferred.get() 才会执行该函数,并且线程id和主线程是一致的.
		而异步求值会自动运行,当然你想获取结果也可以使用 calc_async.get();
	*/
	
	getchar();
    return 0;
}
int main()
{
	std::cout << "当前线程ID:" << std::this_thread::get_id() << std::endl;

	std::mutex mutex;//互斥锁
	std::condition_variable cv;//信号量

	auto fn_worker_thread = [&](int id) {
		std::unique_lock<std::mutex> lock(mutex);
		cv.wait(lock);

		std::cout << "线程ID:" << std::this_thread::get_id() << "lock id:" << id << std::endl;
	};

	for (int i = 0; i < 10; ++i) {
		std::thread run(fn_worker_thread,i);
		run.detach();
	}

	//cv.notify_one();
	cv.notify_all();

	getchar();
    return 0;
}

线程调用类成员函数,需要显示的传递成员函数默认传递的 this 指针,即当前实例化对象指针,后面再传递你需要的参数。

class AsyncTest{
public:
    void print(){
        fprintf(stderr,"print\r\n");
    }
    int calc(int x,int y,int &result){
        result = x + y;
        return result;
    }
};

int main()
{
    AsyncTest test;

    {// call function void print()
        std::future<void> async = std::async(std::launch::async,&AsyncTest::print,&test);
        async.get();
    }

    {// call function int calc(int x,int y,int &result)
        int result = 0;
        int x = 3;
        int y = 4;
        std::future<int> async = std::async(std::launch::async,&AsyncTest::calc,&test,x,y,std::ref(result));
        int output = async.get();
        fprintf(stderr,"x + y = %d output = %d",result,output);
    }

    return 0;
}
posted @ 2017-10-25 00:21  學海無涯  阅读(9116)  评论(0编辑  收藏  举报