【C++】多线程交替打印奇偶数

news2024/11/23 8:24:23

目录

版本1 双信号量版

 版本二 单信号量版

 版本三 信号量版


共享资源是100个数字(一个计数器的++  由两个进程争抢完成)

首先访问临界资源(对计数器++操作)是肯定的要加锁的,交替打印肯定要用条件变量来互相唤醒 互相锁死

也可以使用信号量对临界资源做判断

所以使用wait的时候不需要释放锁 

版本1 双信号量版

唤醒对方条件不满足的信号量 

//双条件变量版本
void thread1() {
	while (true) {
		unique_lock<mutex> locker(mut);  //会自动解锁
		if (g_nums % 2 == 1 && g_nums <= num)
		{
			cout << "Thread1:" << g_nums << endl;
			g_nums++;
		}
		cond2.notify_one();
		cond1.wait(locker);
		if (g_nums >= num+1)
				break;
	}
	cout << "1 done"<< endl;
	cond2.notify_one();
}
 void thread2() {
	while (true) {
		unique_lock<mutex> locker(mut);
		if (g_nums % 2 == 0 && g_nums <= num)
		{
			cout << "Thread2:" << g_nums << endl;
			g_nums++;
		}
		cond1.notify_one();
		cond2.wait(locker);
		if (g_nums >= num + 1)
			break;
	}
	cout << "2 done" << endl;
	cond1.notify_one();
}
int main() {
	thread t1(thread1);
	thread t2(thread2);
	t1.join();
	t2.join();
	cout << "done" << endl;
	return 0;
}

 版本二 单信号量版


//单条件变量版本
void thread1()
{
	while (true)
	{
		unique_lock<mutex> lock(mut);
		if (g_nums % 2 == 1 && g_nums <= num)
		{
			cout << "thread 1:" << g_nums ++<< endl;
			
		}
	       cond.notify_one();  //唤醒另一个进程
			cond.wait(lock); //把当前的进程锁住
			if (g_nums >= num+1)
				break;
	}
	cout << "1 done"<< endl;
	cond.notify_one();
}
void thread2() {
	while (1) {
		unique_lock<mutex> locker(mut);
		if (g_nums % 2 == 0 && g_nums <= num)
		{
			cout << "Thread2:" << g_nums << endl;
			g_nums++;
		}
		cond.notify_one();
		cond.wait(locker);
      if (g_nums >= num+1)
				break;
	}
	cout << "2 done" << endl;
	cond.notify_one();
}
int main() {
	thread t1(thread1);
	thread t2(thread2);
	t1.join();
	t2.join();
	cout << "done" << endl;
	return 0;
}

 版本三 信号量版

C++在语言级别并没有支持semaphore

我们自己实现一个

#pragma once

#include <iostream>
#include <mutex>
#include <condition_variable>

using namespace std;

class semaphore {
public:
	semaphore(int num=0)
		:count(num)
	{
	}
	~semaphore()
	{}
	void single() //V
	{
		unique_lock<mutex> lock(mtx);
		if (++count <= 0)
			cond.notify_one();
	}
	void wait() //p
	{
		unique_lock<mutex> lock(mtx);
		if (--count < 0)
			cond.wait(lock);
	}


private:
	int count;
	mutex mtx;
	condition_variable cond;

};

 然后可以正常使用

 //信号量版本
void thread1()
{
	while (true)
	{
		if (g_nums % 2 == 1 && g_nums <= num)
		{
			cout << "thread 1:" << g_nums++ << endl;
			smp1.single();
		}
		smp2.wait();
		//cond.notify_one();  //唤醒另一个进程
		//cond.wait(lock); //把当前的进程锁住
		if (g_nums >= num + 1)
			break;
	}
	cout << "1 done" << endl;
	smp1.single();
}


void thread2() {
	while (true) {
		if (g_nums % 2 == 0 && g_nums <= num)
		{
			cout << "Thread2:" << g_nums ++<< endl;
			smp2.single();
		}
		smp1.wait();
			if (g_nums >= num+1)
				break;
	}
	cout << "2 done" << endl;
	smp2.single();
}


int main() 
{
	thread t1(thread1);
	thread t2(thread2);
	t1.join();
	t2.join();
	cout << "done" << endl;
	return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/766646.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

计及需求侧响应日前—日内两阶段鲁棒备用优化(matlab代码)

目录 1 主要内容 日前计划模型 日内调整模型 不确定集建模 2 部分代码 3 程序结果 1 主要内容 该程序复现文章《计及需求侧响应日前—日内两阶段鲁棒备用优化》&#xff0c;以6节点系统为例&#xff0c;综合考虑风电出力不确定性与电力设备 N-k强迫停运&#xff0c;增强电…

创建型模式 - 原型模式

概述 用一个已经创建的实例作为原型&#xff0c;通过复制该原型对象来创建一个和原型对象相同的新对象。 结构 原型模式包含如下角色&#xff1a; 抽象原型类&#xff1a;规定了具体原型对象必须实现的的 clone() 方法。 具体原型类&#xff1a;实现抽象原型类的 clone() 方…

如何用3D格式转换工具HOOPS Exchange读取颜色和材料信息?

作为应用程序开发人员&#xff0c;非常希望导入部件的图形表示与它们在创作软件中的外观尽可能接近。外观可以在每个B-Rep面的基础上指定&#xff0c;而且&#xff0c;通过装配层次结构的特定路径可以在视觉外观上赋予父/子覆盖。HOOPS ExchangeHOOPS Exchange可捕获有关来自各…

创建型模式 - 建造者模式

概述 将一个复杂对象的构建与表示分离&#xff0c;使得同样的构建过程可以创建不同的表示。 分离了部件的构造(由Builder来负责)和装配(由Director负责)。 从而可以构造出复杂的对象。这个模式适用于&#xff1a;某个对象的构建过程复杂的情况。 由于实现了构建和装配的解耦。…

虾皮、Lazada爆款打造计划,自养号测评补单技术成重要的运营手段【无标题】

在如今的电商平台中&#xff0c;虾皮和lazada是东南亚地区主要的电商平台&#xff0c;平台广告是它的主要利润来源之一。然而&#xff0c;随着大量卖家涌入东南亚市场&#xff0c;商家之间的竞争也日益激烈&#xff0c;高额的广告投入并没有带来预期的效果。为了提高产品在平台…

【26】SCI易中期刊推荐——计算机人工智能(中科院4区)

💖💖>>>加勒比海带,QQ2479200884<<<💖💖 🍀🍀>>>【YOLO魔法搭配&论文投稿咨询】<<<🍀🍀 ✨✨>>>学习交流 | 温澜潮生 | 合作共赢 | 共同进步<<<✨✨ 📚📚>>>人工智能 | 计算机视觉…

【视频+文字讲解】C++那些事之彻底搞懂STL HashTable

C那些事之彻底搞懂STL HashTable C那些事之彻底搞懂STL HashTable1.常用容器 1.1 接口层2.HashTable原理 2.1 _Hash_node结构2.2 hashtable实现2.3 如何确定桶&#xff1f;2.4 如何确定在桶中的位置&#xff1f;3.Rehash 3.1 计算新桶大小3.2 判断是否需要rehash3.3 rehash 最近…

Github实时数据分析与可视化训练营火热开启!免费领取5000元云上资源

此次训练营内容基于GitHub Archive公开数据集&#xff0c;通过DataWorks将GitHub中的项目、行为等20多种事件类型数据实时采集至Hologres进行分析&#xff0c;同时使用DataV内置模板&#xff0c;快速搭建实时可视化数据大屏&#xff0c;从开发者、项目、编程语言等多个维度了解…

vscode 使用ssh进行远程开发 (remote-ssh)

介绍 visual studio code remote - ssh 可以通过ssh连接远程主机、虚拟机&#xff0c;打开远程文件夹&#xff0c;并利用vscode 的插件优势进行远程开发、调试等。 步骤 一、配置环境 因为remote-ssh 的ssh连接是基于openssh实现的&#xff0c;以及后续我们需要使用生成ss…

手把手教你搭建SpringCloud项目(七)集成Consul服务注册中心

一、了解Consul 这篇文章学习另外一个服务注册中心Consul&#xff0c;那什么是Consul&#xff1f; Consul是一个服务网格&#xff08;微服务间的 TCP/IP&#xff0c;负责服务之间的网络调用、限流、熔断和监控&#xff09;解决方案&#xff0c;它是一个一个分布式的&#xff…

[PCIE体系结构导读]PCIE总结(二)

PMCR&#xff08;Power Management Capabilities Register&#xff09;和PMCSR&#xff08;Power Management Control and Status Register) PMCR寄存器由16位组成&#xff0c;其中所有位和字段都是只读的。该寄存器的主要木得是记录当前PCIe设备的物理属性&#xff0c;系统软件…

vue2的 element 表格单元格合并

<template><div><el-table show-summary :summary-method"getSummaries" :span-method"objectSpanMethod" :data"tableData" row-key"id" ref"tableDom" border><el-table-column label"序号&quo…

10-2. 数组 Array 的实例方法

本文并没有写出数组的全部使用方法&#xff0c;想看全的可以看一下这个 Array - JavaScript | MDN 目录 1 常用内置方法 1.1 合并数组 concat() 1.2 复制元素覆盖到指定位置 copyWithin() 1.3 返回其他变量的数组形式 Array.from() 1.3.1 基本使用 1.3.2 将伪数组…

Hive Metastore、Hive server和Hive thrift服务

Hive Metastore Hive Metastore是Hive的核心元数据管理服务,它提供了元数据的持久化存储和访问控制的能力,使得 Hive 成为一个强大的数据仓库和分析平台,适用于处理大数据和进行复杂的数据查询与分析任务。 Apache Hive是一个建立在 Apache Hadoop 上的数据仓库和分析工具…

java多线程之FutureTask、Future、CompletableFuture

前面已经在多线程创建的时候有提到Future和FutureTask的简单用法&#xff0c;这里详细介绍下FutureTask以及CompletableFuture 一、FutureTask 1、FutureTask简介 FutureTask除了实现Future接口外&#xff0c;还实现了Runnable接口。因此&#xff0c;FutureTask可以交给 Exe…

回溯法实现N皇后问题

题1&#xff1a;&#xff08;需打印矩阵&#xff09; 按照国际象棋的规则&#xff0c;皇后可以攻击与之处在同一行或同一列或同一斜线上的棋子。 n 皇后问题 研究的是如何将 n 个皇后放置在 nn 的棋盘上&#xff0c;并且使皇后彼此之间不能相互攻击。 给你一个整数 n &#…

命名空间,缺省参数与函数重载

目录 一&#xff0c;命名空间 1.何为命名空间 2.命名空间的使用 ​编辑 4.::作用域限定符 3.命名空间的展开 全局展开&#xff1a; 局部展开&#xff1a; 4.嵌套命名空间 二&#xff0c;缺省参数与函数重载 1.什么是缺省参数 2.什么是函数重载 3.两者的冲突 一&…

内部数据泄露:保护数据安全的挑战与解决方案

导语&#xff1a; 在当今数字化时代&#xff0c;数据是企业的核心资产之一。然而&#xff0c;随着科技的快速发展和信息的日益增长&#xff0c;数据安全问题也日益突出。其中&#xff0c;内部数据泄露成为企业所面临的重大挑战之一。本文将探讨内部数据泄露的危害&#xff0c;…

简直太高效了!一篇文章帮你快速了解企业如何实现无纸化办公

随着科技的发展和信息技术的普及&#xff0c;无纸化办公已经成为了现代企业的一个趋势。无纸化办公即指在企业日常工作中&#xff0c;尽量减少或不使用纸张作为工作载体&#xff0c;通过电子邮件、电子文档、电子表格等工具实现信息的传递和共享。无纸化办公不仅有利于环保&…

路由器隔绝广播,为什么还要VLAN?

路由器能隔绝广播&#xff0c;那要VLAN有什么用&#xff0c;既配置了VLAN又划分在不同的网段是不是有些多余了&#xff1f; 题主的意思是不要VLAN&#xff0c;可以吗&#xff1f; 当然可以。可以是可以&#xff0c;但是每台主机都能接收到路由器同一个接口&#xff08;三层/路…