In addition to Weibo, there is also WeChat
Please pay attention
WeChat public account
Shulou
2025-03-26 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >
Share
Shulou(Shulou.com)06/03 Report--
This article mainly explains "how to use QSemaphore for multi-thread data synchronization", the content of the article is simple and clear, easy to learn and understand, now please follow the editor's ideas slowly in depth, together to study and learn "how to use QSemaphore for multi-thread data synchronization" bar!
20210127: add the thread-pending method QThread::usleep (10) to the producer and consumer's method to make the ui not stuck.
20210128: after adding the Track class (saving each set of data generated by the producer Producer), using model-view to synchronously display the data generated by the producer in the ui interface, model-view will not cause stutters to the main thread. View is also created for consumers, and there is no model binding yet.
To avoid blocking the main thread, Qt processes big data in the child thread. When multiple child threads need to process the same piece of data, data synchronization needs to be used to avoid call confusion. Here, we use QSemaphore as the marker bit in the two child threads to identify the array. The producer thread stores the generated resources in the array, and the consumer array consumes the resources in the array. When one party runs so fast that the array runs out of resources, the child thread is blocked until the child thread continues when resources are available. The code is as follows:
Declare the array, the array size, and the total amount of resources in the global variable:
Constant_variable.h
# ifndef CONSTANT_VARIABLE_H#define CONSTANT_VARIABLE_H// all variables are declared in the h file Defined in the cpp file / * @ copyright 2013-2020 @ author qiaowei @ contact weiweiqiao@126.com @ version File 1.0 @ date 2021-01-24 @ brief h declares the extern variable Cpp file defines the variable * / # include / * * * @ copyright 2013-2020 @ author qiaowei @ contact weiweiqiao@126.com @ version 2021 @ date 2021-01-24 @ brief sets the array size of the loop to save the data Equivalent to setting the "cache" size * / extern const int BUFFER_SIZE / * @ copyright 2013-2020 @ author qiaowei @ contact weiweiqiao@126.com @ date 2021-01-24 @ brief the total number of resources to be read is large Cannot be read at once. It takes a long time to read * * / extern const int DATA_SIZE in batches. / * @ copyright 2013-2020 @ author qiaowei @ contact weiweiqiao@126.com @ date 2021-01-24 @ brief Recycle An array of data resources * * / extern char BUFFER [] / * @ copyright 2013-2020 @ author qiaowei @ contact weiweiqiao@126.com @ date 2021-01-24 @ brief identifies the number of places where Producer can save resources The amount of data saved in the array, because there is no data in the initial state array, and the array has DATA_SIZE resources available * / extern QSemaphore PRODUCER_SPACE / * @ copyright 2013-2020 @ author qiaowei @ contact weiweiqiao@126.com @ date 2021-01-24 @ brief identifies the number of saved resources that Consumer can use Because there is no data available for Consumer at the beginning, the initial resource has 0 * / 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); / / define the array size as BUFFER_SIZEchar buffer [buffer _ SIZE]; / / initially available resource bits BUFFER_SIZEQSemaphore PRODUCER_SPACE (BUFFER_SIZE); QSemaphore CONSUMER_SPACE (0)
Create a form:
The Producer button generates resources, saves them to an array, and displays the thread where Producer resides and the generated resources in the text box on the left. The Consumer button consumes resources in the array, showing the thread where Consumer resides and the resources consumed in the text box on the left. These two buttons are run separately. The Both_start_PushButton button starts two child threads at the same time, one production resource, one consumption resources, production and consumption are shown in the text box on the left.
The window code is as follows:
Producer_consumer_dialog.ui Code:
Producer_consumer_dialog 0 0 722 451 Dialog Producer Qt::Vertical QSizePolicy::Expanding 20 40 Consumer Qt::Vertical 20 40 Qt::Horizontal 348 20 Both_start_PushButton
Producer_consumer_dialog.h file:
# ifndef PRODUCER_CONSUMER_DIALOG_H#define PRODUCER_CONSUMER_DIALOG_H#include # include QT_BEGIN_NAMESPACEclass Producer_move_to_thread;class Consumer_move_to_thread;class Producer_table_model;//class QCloseEvent;QT_END_NAMESPACEnamespace Ui {class Producer_consumer_dialog } / * @ copyright 2013-2020 @ author qiaowei @ contact weiweiqiao@126.com @ version 1.0 @ Date 2021-01-27 @ brief create the main window Generate the creator producer and produce resources in child thread-1. Generate consumer consumer and consume production resources in child thread-2. Resources are stored in BUFFER [] * / class Producer_consumer_dialog: public QDialog {Q_OBJECTpublic: 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 Initialize the form control * / void init_widgets () / * @ author qiaowei @ contact weiweiqiao@126.com @ version 1.0 @ date 2021-01-27 @ brief initializes the private variable and sets the producer_ Consumer_ into their respective child threads * / void init_instances () / * @ author qiaowei @ contact weiweiqiao@126.com @ version 1.0 @ date 2021-01-27 @ brief instance Chemical signal slot * / void init_connections () Private slots: / * @ author qiaowei @ contact weiweiqiao@126.com @ version 1.0 @ date 2021-01-27 @ brief Set the string content to the text box producer_plainTextEdit @ param content string * * / 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 String content set to text box consumer_plainTextEdit @ param content string * * / 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 consumption Generate the model corresponding to the data * * / Producer_table_model* producer_table_model_ }; # endif / / PRODUCER_CONSUMER_DIALOG_H
Producer_consumer_dialog.cpp file:
# 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) / / get the string connect generated by producer_ (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) / / get the string connect (consumer_, & Consumer_move_to_thread::signal_string, this, & Producer_consumer_dialog::set_consumer_plain_text) obtained by consumer_ } 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);}
Production category
Producer_move_to_thread.h file:
# ifndef PRODUCER_MOVE_TO_THREAD_H#define PRODUCER_MOVE_TO_THREAD_H#include / * @ copyright 2013-2020 @ author qiaowei @ contact weiweiqiao@126.com @ version 1.0 @ date 2021-01-28 @ brief producer Will be moved to the child thread to generate a resource * / class Producer_move_to_thread: public QObject {Q_ OBJECTpublic: 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 file:
# include # 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) {/ / produce 1 resource (a total of DATA_SZIE resources to be generated), and then save it to the BUFFER array. The spare position of the BUFFER array is reduced by 1 PRODUCER_SPACE.acquire (1); / / calculate to get the resource sequence number, thread number, data resource 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 ()
Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.
Views: 0
*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.
Continue with the installation of the previous hadoop.First, install zookooper1. Decompress zookoope
"Every 5-10 years, there's a rare product, a really special, very unusual product that's the most un
© 2024 shulou.com SLNews company. All rights reserved.