线程同步:锁,条件变量,并发

1)锁mutex

2)条件变量
头文件<condiction_variable>
condition_variable cv;
cv.wait(_lock,谓语)//使用谓语检查是否满足唤醒条件,防止假唤醒

using namespace std;
	mutex _mutex;
	condition_variable cv;
	//condition_variable cv2;
	int num = 1;

	thread th1([&]() {
		int i = 10;
		while (i--)
		{
			std::unique_lock<std::mutex> lock(_mutex);
			cv.wait(lock, [&]() {
				return num == 1;
			});
			cout << "one" << endl;
			num = 2;
			cv.notify_one();
		}

		
	});

	thread th2([&]() {
		int i = 10;
		while (i--)
		{
			std::unique_lock<std::mutex> lock(_mutex);
			cv.wait(lock, [&]() {
				return num == 2;
			});
			cout << "two" << endl;
			num = 1;
			cv.notify_one();
		}
		
		
	});

	th1.join();
	th2.join();

3)并发三剑客, future, promise以及async

async:
不开线程,异步调用一个函数(其实是默认开启后台线程)

int fun_task(int val)
{
	int i = 4;
	while (i--)
	{
		std::this_thread::sleep_for(std::chrono::seconds(1));
	}
	return 12;
}

//异步调用一个函数
int main(int argc,char* argv[])
{
	using namespace std;

	std::future<int> result = std::async(std::launch::async, fun_task, 4);

	for (int i = 0; i < 4; i++)
	{
		std::this_thread::sleep_for(std::chrono::seconds(1));
		std::cout << i << std::endl;
	}
	int _val= result.get();
	cout << _val << endl;

// 使用 std::async 异步调用 fetchDataFromDB
std::futurestd::string resultFromDB = std::async(std::launch::async, fetchDataFromDB, "Data");

std::launch枚举:
std::launch::deferred:这种策略意味着任务将在调用std::future::get()或std::future::wait()函数时延迟执行。换句话说,任务将在需要结果时同步执行。
std::launch::async 标志来明确表明我们希望函数异步执行。
std::launch::async | std::launch::deferred:(默认值)这种策略是上面两个策略的组合。任务可以在一个单独的线程上异步执行,也可以延迟执行,具体取决于实现。

4)std::promise
std::promise 和 std::future 一起使用,可以实现从一个线程向另一个线程传递值或异常的功能。

void producer(std::promise<int> &&promise) {
    // 模拟耗时操作
    std::this_thread::sleep_for(std::chrono::seconds(2));
    int result = 42;
    promise.set_value(result); // 设置值
}

int main() {
    // 创建一个 promise 对象
    std::promise<int> promise;

    // 获取对应的 future 对象
    std::future<int> future = promise.get_future();

    // 在一个新线程中执行 producer 函数
    std::thread t(producer, std::move(promise));

    // 继续执行其他操作
    std::cout << "Doing some other work..." << std::endl;
    std::this_thread::sleep_for(std::chrono::seconds(1));

    // 获取异步任务的结果
    try {
        int result = future.get(); // 阻塞,直到结果可用
        std::cout << "Result: " << result << std::endl;
    } catch (const std::exception &e) {
        std::cerr << "Exception: " << e.what() << std::endl;
    }

    // 等待子线程完成
    t.join();

    return 0;

线程间通信的其他方式:
消息队列如 Boost.Interprocess
共享内存:Boost.Interprocess

5)std::future
包含:
std::future val;
std::shared_future val;共享类型future

std::future::get()/wait()

std::future::get() 是一个阻塞调用,用于获取 std::future 对象表示的值或异常。
如果异步任务还没有完成,get() 会阻塞当前线程,直到任务完成。如果任务已经完成,get() 会立即返回任务的结果
get()只能调用一次
如果有异常,get会抛出

std::future::wait() 也是一个阻塞调用,
如果任务已经完成,wait() 会立即返回。如果任务还没有完成,wait() 会阻塞当前线程,直到任务完成。与 get() 不同,wait() 可以被多次调用

b)获得处理异步任务的结果
std::packaged_task和std::future

posted on   不败剑坤  阅读(12)  评论(0编辑  收藏  举报

相关博文:
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· .NET Core 中如何实现缓存的预热?
· 三行代码完成国际化适配,妙~啊~
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?

导航

< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5
点击右上角即可分享
微信分享提示