【问题标题】:How to display a timer simultaneously with the rest of the program?如何与程序的其余部分同时显示计时器?
【发布时间】:2021-09-29 16:17:17
【问题描述】:

所以我一直在做一个基于终端的测验作为我的第一年项目,我决定在代码中显示一个计时器,但是由于在计时器。

我该如何解决这个问题?

    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
}

【问题讨论】:

    标签: c++ multithreading timer clock ctime


    【解决方案1】:

    这个问题看起来更难。你希望同一个程序同时做两件事。虽然这是当今常见的情况,并且大多数程序都是这样运行的,但这并不是一年级学生所期望的水平。

    你需要的是并发编程,应该是一件很难的事情。

    所以这是我能想到的解决问题的最简单示例。但是,并发困难的:您需要参加一个特殊的课程来了解这里发生了什么以及为什么发生。

    #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&lt;thread&gt; 只是为了能够运行sleep_for 使程序进入睡眠状态。这是一种可移植的方式,但您可以使用其他方法。一般来说,#include&lt;thread&gt; 是 C++ 的并发方式,但我相信这对你来说可能太难了。
    • 那么你就有了所有这些#pragmas。这里不是提供 OpenMP 教程的地方,请自行查找,有很多。
    • critical pragma 引入了一个临界区来保护竞争线程共享的资源(这里:std::cout)。去找一个关于它的教程。
    • 这(两个)线程会在sections pragma 中自动生成,前提是程序已正确编译并在具有至少 2 个内核(物理或虚拟)的处理器上运行。
    • 要运行的线程由section pragma 标识

    就是这样。我希望它对你有用。

    只要它起作用,就找一本关于 OpenMP 和/或 C++11 并发模型的好教程/教科书。

    【讨论】:

    • 对不起,我并没有真正得到代码,但是如果我将我的 int main() 不包括 timer() 放在 my_stuff() 中,那么这应该可以吗?
    • 是的。唯一的问题是std::cout:您需要用#pragma omp critical 保护包含它的每一行。这很不方便,因此您最好将std::cout 包装在一个类或函数中并在那里保护它。如果你不这样做,程序会运行,除了显示,这有时会有点混乱。
    • 你可以认为timermy_stuff是两个独立的程序(进程),与真正独立的程序不同,它们共享一些资源:全局内存(包括std::cout)、打开的文件、堆分配内存('operator new`)等。所有局部变量都是“私有的”,因此无需担心它们。因为它们共享资源,所以它们不是常规的“进程”,而是更轻量级的“线程”。访问共享资源需要一些同步。这需要参加有关并发编程的课程/教程。 OpenMP 可以自动执行大部分任务,但不是全部。
    猜你喜欢
    • 2022-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-04-23
    • 1970-01-01
    • 1970-01-01
    • 2013-09-26
    • 2015-10-02
    • 1970-01-01
    相关资源
    最近更新 更多