c++ - 在两个线程中打印数字
问题描述
我想在两个线程中打印从 0 到 n 的数字。第一个线程中的偶数和第二个线程中的奇数。
如何在我的代码的帮助下打印数字?
电流输出为
AAAA_1
AAAA_2
我希望输入 7:
0 1 2 3 4 5 6 7
我创建了一个类
class PrintOrder {
private:
int limit_;
mutex m_;
condition_variable cv_;
int curNum_ = 0;
public:
PrintOrder(int n) {
limit_ = n;
cout << "AAAA_1\n";
cv_.notify_all();
cout << "AAAA_2\n";
}
void even() {
cout << "EVEN\n";
while (curNum_ <= limit_) {
unique_lock<mutex> lk(m_);
cv_.wait(lk, [this]{return curNum_ % 2 == 0;});
if (curNum_ <= limit_) {
cout << curNum_ << endl;
++curNum_;
}
lk.unlock();
cv_.notify_all();
}
return ;
}
void odd() {
cout << "ODD\n";
while (curNum_ <= limit_) {
unique_lock<mutex> lk(m_);
cv_.wait(lk, [this]{return curNum_ % 2 != 0;});
if (curNum_ <= limit_) {
cout << curNum_ << endl;
++curNum_;
}
lk.unlock();
cv_.notify_all();
}
return ;
}
};
int main(int argc, char *argv[]) {
if (argc != 2) {
cout << "ERROR: Expected console input" << endl;
return -1;
}
int num = atoi(argv[1]);
PrintOrder printOrder(num);
}
我尝试使用函数odd() 和 evene() 创建线程,但函数应该是静态的,这似乎不是我的情况
解决方案
任何被认为是条件状态谓词的数据的引用,无论是读取还是写入,都必须受到用于该目的的互斥锁的保护。这意味着无处不在,包括您的 while 循环的测试条件。
启动线程很简单,只需确保在销毁时加入它们即可。结果看起来像下面的代码(我冒昧地为其添加了一个默认值n=100
,因为我不喜欢输入命令行参数)。
#include <iostream>
#include <string>
#include <thread>
#include <mutex>
#include <condition_variable>
using namespace std;
class PrintOrder final
{
private:
int limit_;
int curNum_;
mutex m_;
condition_variable cv_;
std::thread thr_even, thr_odd;
public:
PrintOrder(int n)
: limit_(n)
, curNum_(0)
{
thr_even = std::thread(&PrintOrder::even, this);
thr_odd = std::thread(&PrintOrder::odd, this);
}
~PrintOrder()
{
thr_even.join();
thr_odd.join();
}
void even()
{
unique_lock<mutex> lk(m_);
while (curNum_ <= limit_)
{
cv_.wait(lk, [this] { return curNum_ % 2 == 0; });
if (curNum_ <= limit_)
{
cout << curNum_ << endl;
++curNum_;
}
cv_.notify_all();
}
}
void odd()
{
unique_lock<mutex> lk(m_);
while (curNum_ <= limit_)
{
cv_.wait(lk, [this] { return curNum_ % 2 != 0; });
if (curNum_ <= limit_)
{
cout << curNum_ << endl;
++curNum_;
}
cv_.notify_all();
}
}
};
int main(int argc, char *argv[])
{
int num = 100;
if (argc == 2)
num = std::stoi(argv[1]);
PrintOrder printOrder(num);
}
输出是您所期望的:从 1 到 100 的数字,每行一个,按顺序排列。
推荐阅读
- sql - 根据引用它的最新订单对产品进行排序 - PostgreSQL
- c - 在C中替换字符串前缀的正确方法
- python - 在使用文件访问时尝试更改对象中的某些值
- python - 安装 YOLOv5 依赖项——torchvision?
- r - 新列包含来自其他 2 列的最少数据
- javascript - 打开新标签页、刷新或关闭浏览器时如何管理 localStorage 和/或 sessionStorage?
- java - 如何在适用于 Android 10+ 的 android studio 中保存 PDF 文档
- python - 在数据框中查找所有匹配的键和值
- javascript - 未捕获的类型错误:无法使用复选框读取 app.js:2 处的 null 属性“addEventListener”
- vue.js - Vuex 为一个特定对象改变存储的键值