Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/136.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ boost::condition会提高性能吗?_C++_Multithreading_Boost_Boost Thread - Fatal编程技术网

C++ boost::condition会提高性能吗?

C++ boost::condition会提高性能吗?,c++,multithreading,boost,boost-thread,C++,Multithreading,Boost,Boost Thread,我们有一个多线程应用程序。在当前的实现中,thread1在启动时创建,并定期(每秒左右,可配置)唤醒以检查磁盘中是否有潜在的保存文件。这些文件由另一个线程保存,thread2。运行thread1及其定期唤醒可能会降低应用程序的速度 现在我们有机会使用boost::condition变量将thread1阻塞,直到thread2通知它。通过这样做,需要创建一个标志,以避免来自thread2的不必要通知,该标志需要同步,并由thread2以高频率(几秒钟内数百次)检查。或thread1每次写入时都会收

我们有一个多线程应用程序。在当前的实现中,thread1在启动时创建,并定期(每秒左右,可配置)唤醒以检查磁盘中是否有潜在的保存文件。这些文件由另一个线程保存,thread2。运行thread1及其定期唤醒可能会降低应用程序的速度

现在我们有机会使用boost::condition变量将thread1阻塞,直到thread2通知它。通过这样做,需要创建一个标志,以避免来自thread2的不必要通知,该标志需要同步,并由thread2以高频率(几秒钟内数百次)检查。或thread1每次写入时都会收到通知

我的问题如下:

  • 在boost::condition实现中,thread1仍然需要频繁唤醒以检查标志,区别在于实现对我们是隐藏的,但它实际上做到了这一点。我说得对吗?Windows和Java中类似的API做同样的事情吗

  • 如果一个线程经常收到多次通知,即使它没有处于等待状态,会发生什么

  • 在我的例子中,它将通过切换到boost::condition实现来提高总体性能?我的意见是否定的

  • 在POSIX和Win32中,boost::condition是使用基于事件的API实现的。从技术上讲,线程在获得事件之前不会醒来
  • 如果在发送信号后线程进入等待状态,则信号将丢失。您应该阅读关于基于事件的模式和实现“生产者/消费者”的策略。您的文件写入/读取示例是经典的生产者/消费者实例。为了避免信号丢失,请执行类似于Wikipedia中的C++11示例:
  • 其思想是,如果thread1不等待条件,它将始终锁定共享互斥体:

    //thread1 - consumer
    void thread1() {
        boost::scoped_lock lock(sharedMutex);
        // shared mutex locked, no events can be sent now
        while(1) {
            // check for files written by thread2
            sharedCond.wait( lock ); // this action unlocks the shared mutex, events can be sent now
        }
    }
    
    //thread2 - producer
    void thread2() {
        boost::scoped_lock lock(sharedMutex); // will wait here until thread 1 starts waiting
        // write files
        sharedCond.notify_one();
    }
    
    三,。性能问题:此更改与性能无关,而是将轮询更改为事件模型。如果您的thread1每1秒唤醒一次,那么切换到事件模型不会改善CPU或I/O负载(每1秒消除文件验证),直到您在频率为几KHz且I/O操作阻塞整个过程的嵌入式系统中运行。 它将提高thread1的反应时间,在轮询模式下,文件更改的最大响应时间为1秒,切换到事件后将立即采取行动。
    另一方面,在事件模型中,thread2的性能可能会降低—在它没有等待任何东西之前,如果它使用condition—它将必须锁定共享互斥体,而共享互斥体可能会在thread1读取文件时一直被锁定。

    检查高频率的标志正是boost::condition允许您避免的
    thread1()
    只需等待设置
    标志

    #include <mutex>
    #include <condition_variable>
    #include <thread>
    
    std::mutex mut;
    bool flag;
    std::condition_variable data_cond;
    
    void thread2()
    {
        //here, writing to a file
        std::lock_guard<std::mutex> lk(mut);
        flag = true;  //a new file is saved
        data_cond.notify_one();
    }
    
    void thread1()
    {
        while(true)
        {
            std::unique_lock<std::mutex> lk(mut);
            data_cond.wait(lk,[]{return flag;});
            //here, processing the file
            flag = false;
            lk.unlock();
        }
    }
    
    #包括
    #包括
    #包括
    std::互斥mut;
    布尔旗;
    std::条件变量数据条件;
    无效线程2()
    {
    //这里,正在写入文件
    标准:锁紧装置lk(mut);
    flag=true;//保存一个新文件
    数据条件通知单();
    }
    void thread1()
    {
    while(true)
    {
    std::唯一锁lk(mut);
    数据条件等待(lk,[{return flag;});
    //这里,处理文件
    flag=false;
    lk.unlock();
    }
    }
    

    这是一个基于清单4_1的C++11代码:

    它取决于boost::condition的实现方式。如果使用系统条件变量,则thread1应在收到通知之前退出计划,在收到通知之前不会唤醒。您提到的标志是在创建新文件时设置,并在thread1处理完此文件后重置?是。thread2设置该标志以使thread1知道文件已准备就绪。thread1将对其进行处理,然后重置该标志。