EA&UML日拱一卒-多任务编程超入门-(9)线程同步
         
                原创
        
    
    
                
             ©著作权归作者所有:来自51CTO博客作者大连木匠的原创作品,请联系作者获取转载授权,否则将追究法律责任        
            
                    
                
问题的提出
线程安全的数据类可以提供一种便利的手段来进行线程之间的数据交换,但是这种方法并没有协调两个线程的动作,这一点从输出结果也可以看出:

从输出可以看出,数据交换要么成功,要么就根本不能进行。这就是线程间没有同步的结果。解决这个问题就需要线程同步处理。
示例代码
本例中定义两个互斥量,dataReady和bufferReady。
void WriteData(int i, 
               QMutex& dataReady, 
               QMutex& bufferReady)
{
    bufferReady.lock();
    cout << "WT:<<<<WriteData:" <<
            i << "<<<<" << endl;
    int buffer[5];
    for(int j = 0; j < 5; ++j)
    {
        buffer[j] = j;
    }
    data_array.setData(buffer, 5);
    dataReady.unlock();
}
WriteData方法首先尝试对bufferReady加锁,如果数据类中没有数据时,加锁操作成功,接下来按照正常逻辑写入数据,最后dataReady解锁,为ReadData创造执行条件。
void ReadData(int i,  
             QMutex& dataReady,
             QMutex& bufferReady)
{
    dataReady.lock();
    cout << "RT:>>>>ReadData:" <<
            i << ">>>>" << endl;
    int buffer[5];
    int data_size =
        data_array.removeData(buffer, 5);
    cout << "RT::----data_size=" <<
            data_size << endl;
    int total = 0;
    for(int k = 0; k < data_size; ++k)
    {
        total += buffer[k];
    }
    cout << "RT:----total="  <<
                     total << endl;
    bufferReady.unlock();
}
ReadData方法首先尝试对dataReady加锁,如果数据类中存在数据时,加锁操作成功,接下来按照正常逻辑读出数据,最后对bufferReady解锁,为WriteData创造执行条件。
int main(int /*argc*/, char*[] /*argv*/)
{
    //define CreateDataTask class.
    class CreateDataTask : public QThread
    {
        QMutex& m_data;
        QMutex& m_buffer;
    public:
        CreateDataTask(QMutex& dataReady, 
                       QMutex& bufferReady)
            :m_data(dataReady)
            ,m_buffer(bufferReady)
        {
        }
    private:
        void run()
        {
            for(int i = 0; i < 10; ++i)
            {
                WriteData(i, m_data, m_buffer);
            }
        }
    };
QMutex dataReady;
    QMutex bufferReady;
::timeBeginPeriod(1);
    dataReady.lock();
    //Create thread object of CreateDataTask.
    CreateDataTask *writer =
       new CreateDataTask(dataReady,  
                          bufferReady);
    //Start Thread.
    writer->start(QThread::NormalPriority);
    for(int i = 0; i < 10; ++i)
    {
        ReadData(i, dataReady, bufferReady);
    }
    timeEndPeriod(1);
    getch();    
    return 0;
}
Main函数中创建了两个互斥量,dataReady和bufferReady,用于读数据操作和和写数据操作。
由于最初没有写入的数据,所以首先调用dataReaday.lock操作,使读数据线程处于阻塞状态。
CreateDataTask类没有另外创建互斥量,而是使用构造函数传递的两个互斥量,然后再传递给WriteData函数。
执行结果

写数据操作,读数据操作整齐地间隔排列,同时数据传递全部正确!
写在文章的最后
 
 本公共号的成长需要您的支持!
 
 阅读更多更新文章,请扫描下面二维码,关注微信公众号【面向对象思考】
 
 
