同时运行同一类的对象

Run objects of the same class simultaneously

本文关键字:一类 对象 运行      更新时间:2023-10-16

我从昨天开始学习C ,我想编写一个警报系统,该警报系统可以用Alarm对象设置自己的警报。我尝试使用的内容本身就可以正常工作,但只能让用户运行一个:如果我尝试使用start方法启动第二个警报,则程序将等待第一个警报" ring"开始第二个。

如何同时运行两个警报?感谢您抽出宝贵的时间阅读本文。(OSX Sierra,Xcode 8.2)

main.cpp

using namespace std;
int main(int argc, const char * argv[]) {
    Alarm test(12, 12, "foo");
    test.start();

alarm.hpp

class Alarm {
    public:
    Alarm(int hour, int minute, std::string speech);
    void start();
    void stop();
    bool isStopped() const;
    std::string getStats() const;
    private:
    int m_hour;
    int m_minute;
    std::string m_speech;
    bool m_stopped;
};

alarm.cpp

using namespace std;
Alarm::Alarm(int hour, int minute, string speech) {
    m_hour = hour;
    m_minute = minute;
    m_speech = speech;
    m_stopped = false;
}
void Alarm::start() {
    int currentHour, currentMinute;
    while (!Alarm::isStopped()) {
        time_t now = time(NULL);
        struct tm *current = localtime(&now);
        currentHour = current->tm_hour;
        currentMinute = current->tm_min;
        if (currentHour == m_hour && currentMinute == m_minute) {
            cout << m_speech << endl;
            m_stopped = true;
        }
        else {
           this_thread::sleep_for(chrono::milliseconds(60000));
        }
     }
}    
void Alarm::stop() {
    m_stopped = true;
}
bool Alarm::isStopped() const {
    return m_stopped;
}

我能想到的最简单的方法是使用 std::thread s:

int main(int argc, const char * argv[]) {        
    Alarm test1(12, 12, "foo");
    Alarm test2(12, 12, "foo");
    std::thread t1(&Alarm::start,test1);
    std::thread t2(&Alarm::start,test2);
    while(!test1.isStopped() && !test2.isStopped()) {
         this_thread::sleep_for(chrono::milliseconds(60000));
    }
    t2.join();
    t1.join();
}

使用std::mutexstd::atomic或类似的m_stopped成员变量:

class Alarm {
    public:
    Alarm(int hour, int minute, std::string speech);
    Alarm(const Alarm& other);
    Alarm& operator=(const Alarm& other);
    void start();
    void stop();
    bool isStopped() const;
//    std::string getStats() const;
    private:
    int m_hour;
    int m_minute;
    std::string m_speech;
    std::atomic<bool> m_stopped;
};

Alarm::Alarm(int hour, int minute, string speech) 
: m_hour(hour),m_minute(minute),m_speech(speech),m_stopped(false) {
}
Alarm::Alarm(const Alarm& other) 
: m_hour(other.m_hour),m_minute(other.m_minute),m_speech(other.m_speech),m_stopped(other.isStopped()) {
}
Alarm& Alarm::operator=(const Alarm& other) {
    m_hour = other.m_hour;
    m_minute = other.m_minute;
    m_speech = other.m_speech;
    m_stopped.store(other.isStopped());
    return *this;
}
void Alarm::start() {
    int currentHour, currentMinute;
    while (!Alarm::isStopped()) {
        time_t now = time(NULL);
        struct tm *current = localtime(&now);
        currentHour = current->tm_hour;
        currentMinute = current->tm_min;
        if (currentHour == m_hour && currentMinute == m_minute) {
            cout << m_speech << endl;
            m_stopped.store(true);
        }
        else {
           this_thread::sleep_for(chrono::milliseconds(1000));
        }
     }
}    

void Alarm::stop() {
    m_stopped.store(true);
}
bool Alarm::isStopped() const {
    return m_stopped.load();
}

请注意,我在上面的示例中进行的有关复制构造函数和分配操作员的定义正确处理std::atomic<bool>成员的更改。


我在这里有一个可编译的版本,并具有正确的参数,应该及时完成并完成。

您需要多线程来执行此操作,但是为了您的情况,我建议检查一个ofter oft oft ofter。

you 可以在自己的线程中运行每个警报,但是对于刚刚开始C 的人来说,这可能有点先进 - 而且无论如何都过高。

处理多个警报的标准方法是搜索所有警报,以查找将首先"戒指"并睡得足够长的警报。当启动时,将其从列表中删除,然后搜索将首先响起的下一个。(如果您将警报保存在排序的容器(例如std::map<time_t, Alarm>甚至std::map<time_t, std::string>)中,则找到第一个警报会更容易

请记住处理案件时需要同时发射一个以上的警报。

如果您希望用户在运行时能够与系统进行交互(例如,添加新的警报,删除警报等),您仍然需要多线程 - 但是您只应该让一个线程为该系统睡觉下一个警报,而不是每个警报的一个线程。