中文字幕日韩精品一区二区免费_精品一区二区三区国产精品无卡在_国精品无码专区一区二区三区_国产αv三级中文在线

怎么使用QSemaphore進(jìn)行多線程數(shù)據(jù)同步

這篇文章主要講解了“怎么使用QSemaphore進(jìn)行多線程數(shù)據(jù)同步”,文中的講解內(nèi)容簡(jiǎn)單清晰,易于學(xué)習(xí)與理解,下面請(qǐng)大家跟著小編的思路慢慢深入,一起來(lái)研究和學(xué)習(xí)“怎么使用QSemaphore進(jìn)行多線程數(shù)據(jù)同步”吧!

創(chuàng)新互聯(lián)服務(wù)項(xiàng)目包括大峪網(wǎng)站建設(shè)、大峪網(wǎng)站制作、大峪網(wǎng)頁(yè)制作以及大峪網(wǎng)絡(luò)營(yíng)銷策劃等。多年來(lái),我們專注于互聯(lián)網(wǎng)行業(yè),利用自身積累的技術(shù)優(yōu)勢(shì)、行業(yè)經(jīng)驗(yàn)、深度合作伙伴關(guān)系等,向廣大中小型企業(yè)、政府機(jī)構(gòu)等提供互聯(lián)網(wǎng)行業(yè)的解決方案,大峪網(wǎng)站推廣取得了明顯的社會(huì)效益與經(jīng)濟(jì)效益。目前,我們服務(wù)的客戶以成都為中心已經(jīng)輻射到大峪省份的部分城市,未來(lái)相信會(huì)繼續(xù)擴(kuò)大服務(wù)區(qū)域并繼續(xù)獲得客戶的支持與信任!

20210127:在生產(chǎn)者、消費(fèi)者的方法中添加線程掛起方法QThread::usleep(10),使ui不卡。

20210128:在添加Track類(保存生產(chǎn)者Producer生成的每組數(shù)據(jù)),在ui界面中使用model-view同步顯示生產(chǎn)者生成的數(shù)據(jù),model-view不會(huì)對(duì)主線程造成卡頓。對(duì)消費(fèi)者同樣創(chuàng)建view,還沒(méi)有進(jìn)行model綁定。

避免引起主線程的阻塞,Qt在子線程中處理大數(shù)據(jù),當(dāng)多個(gè)子線程需要處理同一塊數(shù)據(jù)時(shí),需要使用數(shù)據(jù)同步,避免出現(xiàn)調(diào)用錯(cuò)亂情況,在這里我們?cè)趦蓚€(gè)子線程使用QSemaphore作為標(biāo)志位,對(duì)數(shù)組進(jìn)行標(biāo)識(shí),生產(chǎn)者線程將生成的資源存入數(shù)組,消費(fèi)者數(shù)組消耗數(shù)組內(nèi)的資源,當(dāng)有一方的速度過(guò)快導(dǎo)致數(shù)組資源耗盡時(shí),該子線程被阻塞,直到有資源時(shí)子線程繼續(xù)。代碼如下:

在全局變量中聲明數(shù)組、數(shù)組大小、資源總量:

constant_variable.h

#ifndef CONSTANT_VARIABLE_H
#define CONSTANT_VARIABLE_H

// 所有變量在h文件中均是聲明,定義在cpp文件中

/*****************************************************************************************
  @copyright 2013-2020
  @author    qiaowei
  @contact   weiweiqiao@126.com
  @version   1.0
  @date      2021-01-24
  @brief     h文件聲明extern變量,cpp文件定義變量
******************************************************************************************/

#include <QSemaphore>

/***************************************************************************
  @copyright 2013-2020
  @author    qiaowei
  @contact   weiweiqiao@126.com
  @version   1.0
  @date      2021-01-24
  @brief     設(shè)置循環(huán)保存數(shù)據(jù)的數(shù)組大小,相當(dāng)于設(shè)置“緩存”大小
***************************************************************************/
extern const int BUFFER_SIZE;

/***************************************************************************
  @copyright 2013-2020
  @author    qiaowei
  @contact   weiweiqiao@126.com
  @date      2021-01-24
  @brief     要讀取的總資源數(shù)量,數(shù)據(jù)量大,無(wú)法一次讀取完,需要長(zhǎng)時(shí)間,分批讀取
***************************************************************************/
extern const int DATA_SIZE;

/***************************************************************************
  @copyright 2013-2020
  @author    qiaowei
  @contact   weiweiqiao@126.com
  @date      2021-01-24
  @brief     循環(huán)使用,保存數(shù)據(jù)資源的數(shù)組
***************************************************************************/
extern char BUFFER[];

/***************************************************************************
  @copyright 2013-2020
  @author    qiaowei
  @contact   weiweiqiao@126.com
  @date      2021-01-24
  @brief     標(biāo)識(shí)Producer可以保存資源的空余位置的數(shù)量,保存在數(shù)組中的數(shù)據(jù)量,因?yàn)槌?
             始狀態(tài)數(shù)組中沒(méi)有任何數(shù)據(jù),數(shù)組有DATA_SIZE個(gè)資源可用
***************************************************************************/
extern QSemaphore PRODUCER_SPACE;

/***************************************************************************
  @copyright 2013-2020
  @author    qiaowei
  @contact   weiweiqiao@126.com
  @date      2021-01-24
  @brief     標(biāo)識(shí)Consumer可以使用的已保存資源的數(shù)量,因?yàn)槌跏紩r(shí)沒(méi)有數(shù)據(jù)可供Consumer
             使用,初始資源有0個(gè)
***************************************************************************/
extern QSemaphore CONSUMER_SPACE;

#endif // CONSTANT_VARIABLE_H

constant_variable.cpp

#include "constant_variable.h"

const int BUFFER_SIZE(4096);

const int DATA_SIZE(100000);

// 定義數(shù)組大小為BUFFER_SIZE
char BUFFER[BUFFER_SIZE];

// 初始時(shí)可用資源位BUFFER_SIZE
QSemaphore PRODUCER_SPACE(BUFFER_SIZE);

QSemaphore CONSUMER_SPACE(0);

創(chuàng)建窗體:

怎么使用QSemaphore進(jìn)行多線程數(shù)據(jù)同步

Producer按鈕生成資源,保存到數(shù)組中,在左側(cè)文本框中顯示Producer所在的線程及生成的資源。Consumer按鈕消耗數(shù)組中的資源,在左側(cè)文本框中顯示Consumer所在的線程及消耗的資源。這兩個(gè)按鈕是單獨(dú)運(yùn)行。Both_start_PushButton按鈕同時(shí)啟動(dòng)兩個(gè)子線程,一個(gè)生產(chǎn)資源,一個(gè)消耗資源,生產(chǎn)和消耗的都在左邊的文本框中顯示。

窗口代碼如下:

producer_consumer_dialog.ui 代碼:

<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
 <class>Producer_consumer_dialog</class>
 <widget class="QDialog" name="Producer_consumer_dialog">
  <property name="geometry">
   <rect>
    <x>0</x>
    <y>0</y>
    <width>722</width>
    <height>451</height>
   </rect>
  </property>
  <property name="windowTitle">
   <string>Dialog</string>
  </property>
  <layout class="QVBoxLayout" name="verticalLayout_3">
   <item>
    <layout class="QHBoxLayout" name="horizontalLayout">
     <item>
      <widget class="QPlainTextEdit" name="producer_plainTextEdit"/>
     </item>
     <item>
      <layout class="QVBoxLayout" name="verticalLayout">
       <item>
        <widget class="QPushButton" name="producer_pushButton">
         <property name="text">
          <string>Producer</string>
         </property>
        </widget>
       </item>
       <item>
        <spacer name="verticalSpacer">
         <property name="orientation">
          <enum>Qt::Vertical</enum>
         </property>
         <property name="sizeType">
          <enum>QSizePolicy::Expanding</enum>
         </property>
         <property name="sizeHint" stdset="0">
          <size>
           <width>20</width>
           <height>40</height>
          </size>
         </property>
        </spacer>
       </item>
      </layout>
     </item>
     <item>
      <widget class="QTableView" name="producer_tableView"/>
     </item>
    </layout>
   </item>
   <item>
    <layout class="QHBoxLayout" name="horizontalLayout_2">
     <item>
      <widget class="QPlainTextEdit" name="consumer_plainTextEdit"/>
     </item>
     <item>
      <layout class="QVBoxLayout" name="verticalLayout_2">
       <item>
        <widget class="QPushButton" name="consumer_pushButton">
         <property name="text">
          <string>Consumer</string>
         </property>
        </widget>
       </item>
       <item>
        <spacer name="verticalSpacer_2">
         <property name="orientation">
          <enum>Qt::Vertical</enum>
         </property>
         <property name="sizeHint" stdset="0">
          <size>
           <width>20</width>
           <height>40</height>
          </size>
         </property>
        </spacer>
       </item>
      </layout>
     </item>
     <item>
      <widget class="QTableView" name="consumer_tableView"/>
     </item>
    </layout>
   </item>
   <item>
    <layout class="QHBoxLayout" name="horizontalLayout_3">
     <item>
      <spacer name="horizontalSpacer">
       <property name="orientation">
        <enum>Qt::Horizontal</enum>
       </property>
       <property name="sizeHint" stdset="0">
        <size>
         <width>348</width>
         <height>20</height>
        </size>
       </property>
      </spacer>
     </item>
     <item>
      <widget class="QPushButton" name="both_start_pushButton">
       <property name="text">
        <string>Both_start_PushButton</string>
       </property>
      </widget>
     </item>
    </layout>
   </item>
  </layout>
 </widget>
 <resources/>
 <connections/>
</ui>

producer_consumer_dialog.h 文件:

#ifndef PRODUCER_CONSUMER_DIALOG_H
#define PRODUCER_CONSUMER_DIALOG_H

#include <QDialog>
#include <QThread>

QT_BEGIN_NAMESPACE
class Producer_move_to_thread;
class Consumer_move_to_thread;
class Producer_table_model;
//class QCloseEvent;
QT_END_NAMESPACE

namespace Ui {
class Producer_consumer_dialog;
}

/*****************************************************************************************
  @copyright 2013-2020
  @author    qiaowei
  @contact   weiweiqiao@126.com
  @version   1.0
  @date      2021-01-27
  @brief     創(chuàng)建主窗口,生成創(chuàng)造者producer,并在子線程-1生產(chǎn)資源。生成消費(fèi)者consumer,并在子線程-2消耗生
             產(chǎn)資源。資源均存儲(chǔ)在BUFFER[]中
******************************************************************************************/
class Producer_consumer_dialog : public QDialog
{
    Q_OBJECT

public:
    explicit Producer_consumer_dialog(QWidget *parent = nullptr);
    ~Producer_consumer_dialog();

protected:
    virtual void closeEvent(QCloseEvent* ev);

private:
    /***************************************************************************
     @author   qiaowei
     @contact  weiweiqiao@126.com
     @version  1.0
     @date     2021-01-27
     @brief    初始化窗體控件
    ***************************************************************************/
    void init_widgets();

    /***************************************************************************
     @author   qiaowei
     @contact  weiweiqiao@126.com
     @version  1.0
     @date     2021-01-27
     @brief    初始化私有變量,將producer_,consumer_放入各自的子線程
    ***************************************************************************/
    void init_instances();

    /***************************************************************************
     @author   qiaowei
     @contact  weiweiqiao@126.com
     @version  1.0
     @date     2021-01-27
     @brief    實(shí)例化信號(hào)槽
    ***************************************************************************/
    void init_connections();

private slots:
    /***************************************************************************
     @author   qiaowei
     @contact  weiweiqiao@126.com
     @version  1.0
     @date     2021-01-27
     @brief    將字符串content設(shè)置到文本框producer_plainTextEdit
     @param    content 字符串
    ***************************************************************************/
    void set_producer_plain_text(quint32 serial_number, quint64 thread_id, char ch);

    /***************************************************************************
     @author   qiaowei
     @contact  weiweiqiao@126.com
     @version  1.0
     @date     2021-01-27
     @brief    將字符串content設(shè)置到文本框consumer_plainTextEdit
     @param    content 字符串
    ***************************************************************************/
    void set_consumer_plain_text(QString content);

private:
    Ui::Producer_consumer_dialog *ui;

    Producer_move_to_thread* producer_;
    Consumer_move_to_thread* consumer_;

    QThread producer_thread_;
    QThread consumer_thread_;

    /***************************************************************************
     @author   qiaowei
     @contact  weiweiqiao@126.com
     @version  1.0
     @date     2021-01-28
     @brief    消費(fèi)者產(chǎn)生數(shù)據(jù)對(duì)應(yīng)的模型
    ***************************************************************************/
    Producer_table_model* producer_table_model_;
};

#endif // PRODUCER_CONSUMER_DIALOG_H

producer_consumer_dialog.cpp文件:

#include "producer_consumer_dialog.h"
#include "ui_producer_consumer_dialog.h"

#include "producer_move_to_thread.h"
#include "consumer_move_to_thread.h"
#include "producer_table_model.h"

Producer_consumer_dialog::Producer_consumer_dialog(QWidget *parent) :
    QDialog(parent),
    ui(new Ui::Producer_consumer_dialog)
{
    ui->setupUi(this);

    init_widgets();
    init_instances();
    init_connections();
}

Producer_consumer_dialog::~Producer_consumer_dialog()
{
    delete producer_;
    delete consumer_;
    delete producer_table_model_;

    delete ui;
}

void Producer_consumer_dialog::closeEvent(QCloseEvent *ev)
{
//    QThread::sleep(3);
    if ( producer_thread_.isRunning()) {
        producer_thread_.quit();
        producer_thread_.wait();
    }

    if ( consumer_thread_.isRunning()) {
        consumer_thread_.quit();
        consumer_thread_.wait();
    }

    QDialog::closeEvent(ev);
}

void Producer_consumer_dialog::init_widgets()
{
//    setFixedSize(sizeHint());
    resize(sizeHint());
}

void Producer_consumer_dialog::init_instances()
{
    producer_ = new Producer_move_to_thread();
    producer_->moveToThread(&producer_thread_);
    producer_thread_.start();

    consumer_ = new Consumer_move_to_thread();
    consumer_->moveToThread(&consumer_thread_);
    consumer_thread_.start();

    producer_table_model_ = new Producer_table_model();
    ui->producer_tableView->setModel(producer_table_model_);
}

void Producer_consumer_dialog::init_connections()
{
    connect(ui->producer_pushButton,
            &QPushButton::clicked,
            producer_,
            &Producer_move_to_thread::create_char_in_thread);

    connect(ui->consumer_pushButton,
            &QPushButton::clicked,
            consumer_,
            &Consumer_move_to_thread::create_char_in_thread);

    connect(ui->both_start_pushButton,
            &QPushButton::clicked,
            ui->producer_pushButton,
            &QPushButton::clicked);

    connect(ui->both_start_pushButton,
            &QPushButton::clicked,
            ui->consumer_pushButton,
            &QPushButton::clicked);

    // 獲取producer_生成的字符串
    connect(producer_,
            &Producer_move_to_thread::signal_index_id_content,
            this,
            &Producer_consumer_dialog::set_producer_plain_text);

    connect(producer_,
            &Producer_move_to_thread::signal_index_id_content,
            producer_table_model_,
            &Producer_table_model::add_data_to_track_list);

    // 獲取consumer_取得的字符串
    connect(consumer_,
            &Consumer_move_to_thread::signal_string,
            this,
            &Producer_consumer_dialog::set_consumer_plain_text);
}

void Producer_consumer_dialog::set_producer_plain_text(quint32 serial_number, quint64 thread_id, char ch)
{
    QString content =
            QString("%1: Producer thread id: %2, char: %3").
            arg(serial_number).
            arg(thread_id).
            arg(ch);
    ui->producer_plainTextEdit->appendPlainText(content);
//    ui->producer_plainTextEdit->setPlainText(content);
}

void Producer_consumer_dialog::set_consumer_plain_text(QString content)
{
    ui->consumer_plainTextEdit->appendPlainText(content);
//    ui->consumer_plainTextEdit->setPlaceholderText(content);
}

生產(chǎn)類

producer_move_to_thread.h 文件:

#ifndef PRODUCER_MOVE_TO_THREAD_H
#define PRODUCER_MOVE_TO_THREAD_H

#include <QObject>

/*****************************************************************************************
  @copyright 2013-2020
  @author    qiaowei
  @contact   weiweiqiao@126.com
  @version   1.0
  @date      2021-01-28
  @brief     生產(chǎn)者,會(huì)被移動(dòng)到子線程中產(chǎn)生資源
******************************************************************************************/
class Producer_move_to_thread : public QObject
{
    Q_OBJECT

public:
    explicit Producer_move_to_thread(QObject *parent = nullptr);
    ~Producer_move_to_thread();

signals:
//    void signal_string(quint32 serial_number, quint64 thread_id, char ch);

    void signal_index_id_content(quint32 index, int id, char ch);

public slots:
    void create_char_in_thread();
};

#endif // PRODUCER_MOVE_TO_THREAD_H

producer_move_to_thread.cpp 文件:

#include <QtDebug>
#include <QThread>
#include <QtGlobal>
#include "producer_move_to_thread.h"
#include "constant_variable.h"

Producer_move_to_thread::Producer_move_to_thread(QObject* parent):
    QObject(parent)
{

}

Producer_move_to_thread::~Producer_move_to_thread()
{

}

void Producer_move_to_thread::create_char_in_thread()
{
    for (int index(0); DATA_SIZE != index; ++index) {
        // 生產(chǎn)1個(gè)資源(總共要產(chǎn)生的DATA_SZIE個(gè)資源),然后保存到BUFFER數(shù)組,BUFFER數(shù)組空余位置少1個(gè)
        PRODUCER_SPACE.acquire(1);

        // 計(jì)算獲取資源序號(hào)、線程號(hào)、數(shù)據(jù)資源
        quint32 serial_number = (quint32) (index + 1);
        quint64 thread_id = (quint64) QThread::currentThreadId();
        char ch = "ABCDXYZ"[uint(std::rand()) % 7];
        BUFFER[index % BUFFER_SIZE] = ch;

        qDebug()<< "Produce thread id: " << thread_id
                << ", char: " <<  ch;

        // 將數(shù)據(jù)傳給窗體Producer_consumer_dialog
//        emit signal_string(serial_number, thread_id, ch);

        emit signal_index_id_content(serial_number, thread_id, ch);

        // 線程掛起,不對(duì)主線程造成卡頓
        QThread::usleep(10);

        // 數(shù)組中已保存1個(gè)字符,Consumer獲取1個(gè)可用資源
        CONSUMER_SPACE.release(1);
    }
}

資源消耗類

consumer_move_to_thread.h 文件:

#ifndef CONSUMER_MOVE_TO_THREAD_H
#define CONSUMER_MOVE_TO_THREAD_H

#include <QObject>

class Consumer_move_to_thread : public QObject
{
    Q_OBJECT
public:
    explicit Consumer_move_to_thread(QObject *parent = nullptr);

signals:
    void signal_string(QString content);

public slots:
    void create_char_in_thread();
};

#endif // CONSUMER_MOVE_TO_THREAD_H

consumer_move_to_thread.cpp文件:

#include <QtDebug>
#include <QThread>
#include "consumer_move_to_thread.h"
#include "constant_variable.h"

Consumer_move_to_thread::Consumer_move_to_thread(QObject *parent) :
    QObject(parent)
{

}

void Consumer_move_to_thread::create_char_in_thread()
{
    for (int index(0); DATA_SIZE != index; ++index) {
        // 消耗1個(gè)資源(總共要消耗DATA_SZIE個(gè)資源),從BUFFER數(shù)組中取出,BUFFER數(shù)組空余位置多1個(gè)。當(dāng)
        // 沒(méi)有資源提供時(shí),進(jìn)程被掛起,待有足夠資源后再執(zhí)行后續(xù)程序
        CONSUMER_SPACE.acquire(1);

        qDebug()<< "Consumer thread id: " << (quint64) QThread::currentThreadId()
                << ", char: " << (char) BUFFER[index % BUFFER_SIZE];

        QString content =
                QString("%1: Consumer thread id: %2, char: %3").
                arg(index + 1).
                arg((quint64) QThread::currentThreadId()).
                arg(BUFFER[index % BUFFER_SIZE]);

        emit signal_string(content);
        //線程掛起,不對(duì)主線程造成卡頓
        QThread::usleep(10);

        // 使用數(shù)組中1個(gè)資源,數(shù)組釋放1個(gè)空間,給生產(chǎn)者提供1個(gè)空余位置
        PRODUCER_SPACE.release(1);
    }
}

保存生產(chǎn)者生成的數(shù)據(jù)Track類:

Track.h

#ifndef TRACK_H
#define TRACK_H

#include <QtGlobal>

/*****************************************************************************************
  @copyright 2013-2020
  @author    qiaowei
  @contact   weiweiqiao@126.com
  @version   1.0
  @date      2021-01-28
  @brief     數(shù)據(jù)類,保存隨機(jī)生成的資源
******************************************************************************************/
class Track
{
public:
    /***************************************************************************
     @author   qiaowei
     @contact  weiweiqiao@126.com
     @version  1.0
     @date     2021-01-28
     @brief    構(gòu)造函數(shù)
     @param    index 數(shù)據(jù)的生成序列號(hào)
     @param    thread_id 生成數(shù)據(jù)的線程號(hào)
     @param    ch 生成的資源數(shù)據(jù)
    ***************************************************************************/
    explicit Track(quint32 index = 0, quint64 thread_id = 0, char ch = 'A');
    ~Track();

    /***************************************************************************
     @author   qiaowei
     @contact  weiweiqiao@126.com
     @version  1.0
     @date     2021-01-28
     @brief    拷貝構(gòu)造函數(shù)
    ***************************************************************************/
    Track(const Track& r_value);

    /***************************************************************************
     @author   qiaowei
     @contact  weiweiqiao@126.com
     @version  1.0
     @date     2021-01-28
     @brief    賦值操作符
    ***************************************************************************/
    Track& operator = (const Track& r_value);

    quint32 get_index() const;

    quint64 get_thread_id() const;

    char get_char() const;

private:
    quint32 index_;
    quint64 thread_id_;
    char char_;
};

#endif // TRACK_H

Track.cpp

#include "track.h"


Track::Track(quint32 index, quint64 thread_id, char ch):
    index_(index),
    thread_id_(thread_id),
    char_(ch)
{

}

Track::~Track()
{

}

Track::Track(const Track &r_value)
{
    index_ = r_value.index_;
    thread_id_ = r_value.thread_id_;
    char_ = r_value.char_;
}

Track &Track::operator =(const Track &r_value)
{
    if (this != &r_value) {
        index_ = r_value.index_;
        thread_id_ = r_value.thread_id_;
        char_ = r_value.char_;
    }

    return *this;
}

quint32 Track::get_index() const
{
    return index_;
}

quint64 Track::get_thread_id() const
{
    return thread_id_;
}

char Track::get_char() const
{
    return char_;
}

生產(chǎn)者模型Produer_table_model類:

Produer_table_model.h

#ifndef PRODUCER_TABLE_MODEL_H
#define PRODUCER_TABLE_MODEL_H

#include <QAbstractTableModel>
#include <QObject>
#include "track.h"

/*****************************************************************************************
  @copyright 2013-2020
  @author    qiaowei
  @contact   weiweiqiao@126.com
  @version   1.0
  @date      2021-01-28
  @brief
******************************************************************************************/
class Producer_table_model : public QAbstractTableModel
{
    Q_OBJECT

public:
    explicit Producer_table_model(QObject* parent = nullptr);
    ~Producer_table_model();

    void add_data_to_track_list(quint32 serial_number, quint64 thread_id, char ch);

    QList<Track>* get_track_list();

protected:
    virtual int rowCount(const QModelIndex &parent = QModelIndex()) const;

    virtual int columnCount(const QModelIndex& parent = QModelIndex()) const;

    virtual QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const;

    virtual QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const;

private:
    QList<Track>* track_list_;
};

#endif // PRODUCER_TABLE_MODEL_H

Produer_table_model.cpp

#include "producer_table_model.h"

Producer_table_model::Producer_table_model(QObject* parent):
    QAbstractTableModel(parent),
    track_list_(new QList<Track>())
{

}

Producer_table_model::~Producer_table_model()
{
    delete track_list_;
}

void Producer_table_model::add_data_to_track_list(quint32 serial_number, quint64 thread_id, char ch)
{
    track_list_->append(Track(serial_number, thread_id, ch));

    QModelIndex header_model_index = createIndex(serial_number - 1, 0);
    QModelIndex tail_model_index = createIndex(serial_number - 1, 2);

    layoutChanged();
}

QList<Track> *Producer_table_model::get_track_list()
{
    return track_list_;
}

int Producer_table_model::rowCount(const QModelIndex &parent) const
{
    Q_UNUSED(parent)

    if ( track_list_) {
        return track_list_->count();
    } else {
        return 0;
    }
}

int Producer_table_model::columnCount(const QModelIndex &parent) const
{
    Q_UNUSED(parent)

//    // 序號(hào)、線程號(hào)、數(shù)據(jù)資源
//    return 3;

    // 線程號(hào)、數(shù)據(jù)資源
    return 2;
}

QVariant Producer_table_model::data(const QModelIndex &index, int role) const
{
    if ( !index.isValid()) {
        return QVariant();
    }

    QVariant v;
    if (Qt::DisplayRole == role) {
        switch (index.column()) {
        case 0:
            v = track_list_->at(index.row()).get_thread_id();
            break;

        case 1:
            v = (QChar) track_list_->at(index.row()).get_char();
            break;
        }

        return v;
    }



    return QVariant();
}

QVariant Producer_table_model::headerData(int section, Qt::Orientation orientation, int role) const
{
    if ((Qt::DisplayRole == role) &&
            (Qt::Horizontal == orientation)) {

        QString header_content;
        switch (section) {
        case 0:
            header_content = tr("線程號(hào)");
            break;

        case 1:
            header_content = tr("數(shù)據(jù)");
            break;
        }

        return header_content;
    }

    return QAbstractTableModel::headerData(section, orientation, role);
}

在這里特別注意PRODUCER_SPACE和CONSUMER_SPACE的初始值,因?yàn)橘Y源BUFFER數(shù)組初始資源為0,所以生產(chǎn)者Producer可用的數(shù)組空間為所有,消耗著Consumer可用的數(shù)組空間為0,因?yàn)闆](méi)有資源可用。

運(yùn)行結(jié)果如下圖:

怎么使用QSemaphore進(jìn)行多線程數(shù)據(jù)同步

感謝各位的閱讀,以上就是“怎么使用QSemaphore進(jìn)行多線程數(shù)據(jù)同步”的內(nèi)容了,經(jīng)過(guò)本文的學(xué)習(xí)后,相信大家對(duì)怎么使用QSemaphore進(jìn)行多線程數(shù)據(jù)同步這一問(wèn)題有了更深刻的體會(huì),具體使用情況還需要大家實(shí)踐驗(yàn)證。這里是創(chuàng)新互聯(lián),小編將為大家推送更多相關(guān)知識(shí)點(diǎn)的文章,歡迎關(guān)注!

網(wǎng)頁(yè)標(biāo)題:怎么使用QSemaphore進(jìn)行多線程數(shù)據(jù)同步
文章網(wǎng)址:http://www.rwnh.cn/article42/jeesec.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供域名注冊(cè)、動(dòng)態(tài)網(wǎng)站建站公司、云服務(wù)器虛擬主機(jī)、網(wǎng)站營(yíng)銷

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)

外貿(mào)網(wǎng)站制作
汕尾市| 五原县| 宝坻区| 通渭县| 石渠县| 吉水县| 三台县| 定远县| 桃园市| 遂溪县| 贵溪市| 天气| 仙游县| 铁岭市| 合川市| 辰溪县| 特克斯县| 万安县| 通渭县| 双牌县| 太谷县| 呼玛县| 双辽市| 隆昌县| 莱芜市| 湖口县| 临清市| 黎城县| 黑山县| 若尔盖县| 阿巴嘎旗| 库车县| 民丰县| 郑州市| 都匀市| 延寿县| 浑源县| 崇明县| 韶关市| 额敏县| 图们市|