【问题标题】:boost::thread passing data between threadsboost::thread 在线程之间传递数据
【发布时间】:2015-06-12 17:59:24
【问题描述】:

我正在尝试使用 boost::thread 在我的主线程类的两个子类之间传递数据。我对多线程非常陌生,而且有点过头了。现在代码重复生成以下内容。

Reader Api: 0

以下是我的类和子类定义。线程类是一个单例。

class threading
{
public:
    static threading *Instance();
    void workerFunc();
    void workerFunc2();
    void inputWorkerFunc();  // handles input processing

    void producer();
    void consumer();


    int getGlobalVariable()  // retrieves the value of globalVariable
    {
        return (globalVariable);
    } 
    void setGlobalVariable(int set) // sets the value of globalVariable 
    {
        globalVariable = set;
    }

    class Reader   
    {
        public:
        Reader(int waitTime) { _waitTime = waitTime;}
        void operator() () 
        {
            threading *thread = threading::Instance();
            int globalVariable = thread->getGlobalVariable();
            for (int i=0; i < 10; i++) 
            {
                logMsg("Reader Api: " +Ogre::StringConverter::toString(globalVariable));
//       usleep(_waitTime);
                boost::this_thread::sleep(boost::posix_time::microseconds(_waitTime));
            }
            return;
        }
    private:
        int _waitTime;
    };


    class Writer
    {
        public:
            Writer(int variable, int waitTime)
            {
                _writerVariable = variable;
                logMsg("Writer Variable: " +Ogre::StringConverter::toString(_writerVariable));

                _waitTime = waitTime;
            }
            void operator () () 
            {
                logMsg("Writer Variable: " +Ogre::StringConverter::toString(_writerVariable));

                threading *thread = threading::Instance();
                int globalVariable = thread->getGlobalVariable();
                for (int i=0; i < 10; i++) 
                {
//        usleep(_waitTime);
                    boost::this_thread::sleep(boost::posix_time::microseconds(_waitTime));
                    logMsg("Waittime Variable: " +Ogre::StringConverter::toString(_waitTime));

                    // Take lock and modify the global variable
                    boost::mutex::scoped_lock lock(_writerMutex);
                    globalVariable = _writerVariable;
                    thread->setGlobalVariable(globalVariable);

                    _writerVariable++;
                    // since we have used scoped lock, 
                    // it automatically unlocks on going out of scope
                }   
                logMsg("Writer Variable: " +Ogre::StringConverter::toString(_writerVariable));
//                    thread->setGlobalVariable(globalVariable);
            }   
        private:
            int _writerVariable;
            int _waitTime;
            static boost::mutex _writerMutex;
    };

protected:
    threading();
    threading(const threading&);
    threading& operator= (const threading&); 
private:
    static threading *pInstance;       
int globalVariable; 
    boost::mutex mutex;
    boost::condition_variable condvar;
    typedef boost::unique_lock<boost::mutex> lockType;
    double value;
    int count;
 };

这是我在主代码中调用类的方式:

threading *thread = threading::Instance();
threading::Reader reads(100);
threading::Writer writes1(100, 200);
threading::Writer writes2(200, 200);

boost::thread readerThread(reads);
boost::thread writerThread1(writes1);
boost::this_thread::sleep(boost::posix_time::microseconds(100));

boost::thread writerThread2(writes2);

readerThread.join();
writerThread1.join();
writerThread2.join();

【问题讨论】:

  • 您应该在数据的上下文中(这里是 global_mutex)而不是在读取器或写入器的上下文中(如您所做的那样)有一个互斥锁。请将该互斥锁也锁定在阅读器中

标签: c++ multithreading class boost


【解决方案1】:

您显然缺少像(全局)互斥锁这样的体面同步机制,以防止使用此代码出现竞争条件:

static std::mutex globalVariableProtector;

int getGlobalVariable()  // retrieves the value of globalVariable
{
    std::lock_guard<std::mutex> lock(globalVariableProtector);
    return (globalVariable);
} 
void setGlobalVariable(int set) // sets the value of globalVariable 
{
    std::lock_guard<std::mutex> lock(globalVariableProtector);
    globalVariable = set;
}

此外,您实际上应该考虑将该变量放入生产者线程的类中,并为其提供 getter/setter 函数,而不是使用全局变量。


我一直在分享current standard references,而不是boost。 Boost 可能有自己的lock_guardsSynchronized Data Structures 机制,如果你出于某种原因不能使用当前的c++ 标准。

【讨论】:

  • @MikeMcLean 请不要在 cmets 中发布任何其他代码。可能更好的选择是提出一个新问题,准确描述您修改后的代码遇到的问题。不要忘记向MCVE 提供您的新问题。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-04-27
  • 2014-10-12
  • 1970-01-01
  • 1970-01-01
  • 2017-07-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多