问题描述
所以我一直在做一个基于终端的测验作为我的第一年项目,我决定在代码中显示一个计时器,但计时器不让程序继续,原因是程序中使用了无限循环计时器。
我该如何解决这个问题?
void timer()
{
while (true) {
clock_display();//Function loaded with manipulators to just show the 00:00:00 interface
sleep(1);
sec++;
if (sec == 60) {
mins++;
if (mins == 60) {
hrs++;
mins = 0;
}
sec = 0;
}
}
}
int main(){
timer();
//Other code I have to run
}
解决方法
这个问题看起来更难。你希望同一个程序同时做两件事。虽然这在当今很常见,而且大多数课程都以这种方式运行,但这并不是一年级学生所期望的水平。
你需要的是并发编程,这应该是一件很难的事情。
这是我能想到的解决您问题的最简单示例。然而,并发是困难的:您需要学习一门特殊的课程来了解这里发生了什么以及为什么发生。
#include <iostream>
#include <thread>
#include <cmath>
void timer()
{
int sec = 0;
while (true)
{
#pragma omp critical
std::cout << sec++ << "\n";
std::this_thread::sleep_for(std::chrono::duration<double>(1.0));
}
}
void my_stuff()
{
for (int i = 0; i < 100; i++)
{
double x = 0.0;
for (int j = 0; j < 10'000'000; j++)
{
x += sin(i + j);
}
#pragma omp critical
std::cout << "x = " << x << "\n";
}
}
int main()
{
#pragma omp parallel
#pragma omp sections
{
#pragma omp section
timer();
#pragma omp section
my_stuff();
}
}
将其编译为使用 OpenMP 的 C++ 程序:这是最简单的并发库。在 Linux 下:将 -fopenmp
添加到编译器标志中,对于其他操作系统,互联网上有很多答案。
- 我使用
#include<thread>
只是为了能够运行sleep_for
以使程序进入睡眠状态。这是一种可移植的方式,但您可以使用其他方法。通常,#include<thread>
是 C++ 的并发方式,但我相信这对您来说可能太难了。 - 那么您就有了所有这些
#pragma
。这不是 OpenMP 教程的地方,请自行查找,其中有很多。 -
critical
pragma 引入了一个临界区来保护竞争线程共享的资源(此处:std::cout
)。去寻找有关它的教程。 - (两个)线程会在
sections
pragma 中自动生成,前提是程序已正确编译并在至少具有 2 个内核(物理或虚拟)的处理器上运行。 - 要运行的线程由
section
编译指示标识
就是这样。我希望它对你有用。
一旦它起作用,就找一本关于 OpenMP 和/或 C++11 并发模型的好的教程/教科书。