{"id":643,"date":"2024-09-08T07:18:39","date_gmt":"2024-09-08T07:18:39","guid":{"rendered":"https:\/\/blog.vishnumuthu.com\/?p=643"},"modified":"2025-02-25T14:44:23","modified_gmt":"2025-02-25T14:44:23","slug":"a-simple-understanding-of-qthread","status":"publish","type":"post","link":"https:\/\/blog.vishnumuthu.com\/index.php\/2024\/09\/08\/a-simple-understanding-of-qthread\/","title":{"rendered":"A simple understanding of qthread"},"content":{"rendered":"\n<div class=\"wp-block-buttons alignwide is-content-justification-center is-layout-flex wp-container-core-buttons-is-layout-a89b3969 wp-block-buttons-is-layout-flex\">\n<div class=\"wp-block-button\"><a class=\"wp-block-button__link wp-element-button\" href=\"https:\/\/blog.vishnumuthu.com\/index.php\/2024\/09\/08\/a-simple-understanding-of-qt-qml-cmake\/\">Previous post: A simple understanding of qt, QML, cmake<\/a><\/div>\n<\/div>\n\n\n\n&nbsp;<p class=\"has-medium-font-size\"><strong>A simple understanding of qthread<\/strong><\/p>\n\n<p class=\"has-normal-font-size\" style=\"text-indent:.2in;\">The Example <a href=\"https:\/\/github.com\/vishnumuthu\/qt_qthread\"><strong>qt_qthread github link<\/strong><\/a>,\nCreate a simple working for qt qthread with cmake to show the working of Multi-thread array. <\/p>\n\n<p class=\"has-normal-font-size\" style=\"text-indent:.2in;\">* The example shows the reading the number of thread count<\/p>\n\n<p class=\"has-normal-font-size\" style=\"text-indent:.2in;\">* The example shows creating multiple thread using dynamic array object and Qvector with signal\/slot.<\/p>\n\n<p class=\"has-normal-font-size\" style=\"text-indent:.2in;\">* The example shows difference between std::cout and qDebug() output. <\/p>\n\n&nbsp;<p class=\"has-medium-font-size\"><strong>MultiThread<\/strong><\/p>\n\n<p class=\"has-normal-font-size\" style=\"text-indent:.2in;\">C++ offers robust support for <strong>multithreading,<\/strong> allowing programs to perform multiple tasks concurrently, which can greatly enhance performance, especially on modern multi-core processors. Using the C++ Standard Library (since C++11), developers can create and manage threads. Multithreading enables the execution of independent tasks in parallel, such as handling I\/O operations, performing computations, or managing real-time data.<\/p>\n\n<p class=\"has-normal-font-size\" style=\"text-indent:.2in;\">C++ also provides synchronization mechanisms and condition variables to manage access to shared resources and ensure thread safety, avoiding issues like race conditions and deadlocks. Overall, C++&#8217;s multithreading capabilities make it ideal for high-performance and concurrent systems such as game engines, real-time processing, and large-scale applications.<\/p>\n\n<p class=\"has-normal-font-size\" style=\"text-indent:.2in;\">In Qt,<strong> QThread<\/strong> is the class used to handle multithreading by allowing developers to move work to separate threads, enabling concurrency in an application. By subclassing QThread or using worker objects with moveToThread(), you can run tasks in parallel without blocking the main GUI thread, ensuring a responsive user interface. QThread provides signals like started() and finished() to track thread execution, and its event loop allows communication between threads through signals and slots, making it a powerful tool for managing background tasks, long-running operations, and real-time processing in Qt applications.<\/p>\n\n&nbsp;<p class=\"has-medium-font-size\"><strong>Create Thread as Array:<\/strong><\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>\/\/thread_object.h\nclass Thread_object : public QThread\n{\n    Q_OBJECT\npublic:\n    explicit Thread_object(QObject *parent = nullptr);\n\n    void get_limit(int start, int end);\n\n    void run();\nprivate:\n    int mStart, mEnd;\n};\n\n\/\/thread_object.cpp\nvoid Thread_object::get_limit(int start, int end)\n{\n    mStart = start;\n    mEnd = end;\n}\nvoid Thread_object::run()\n{\n    for(int i = mStart; i &lt;= mEnd; i++)\n        qDebug()  &lt;&lt; i ; \/\/std::cout &lt;&lt; i &lt;&lt; std::endl;\n}\n<\/code><\/pre>\n\n\n\n<pre class=\"wp-block-code\"><code>\/\/main.cpp\nQThread cpuInfo; \/\/get CPU info\n    std::cout &lt;&lt; cpuInfo.idealThreadCount() &lt;&lt; std::endl;\n    int index_start = 0, index_end = 99;\n    int count_thread = cpuInfo.idealThreadCount();\n    Thread_object *obj = new Thread_object&#91;count_thread]; \/\/ Thread as Array\n    int avg_count = (index_end - index_start) \/ count_thread;\n    std::cout &lt;&lt; \"Avg: \" &lt;&lt; avg_count &lt;&lt; std::endl;\n    for(int i = 0; i &lt; count_thread; i++)\n    {\n        if(i == 0) \/\/ Start\n        {\n            obj&#91;i].get_limit(index_start, avg_count);\n            obj&#91;i].start();\n        }\n        else if(i == count_thread - 1) \/\/ End\n        {\n            obj&#91;i].get_limit((avg_count * i) + 1, index_end);\n            obj&#91;i].start();\n        }\n        else \/\/ Middle\n        {\n            obj&#91;i].get_limit((avg_count * i) + 1, avg_count * (i + 1));\n            obj&#91;i].start();\n        }\n    }\n<\/code><\/pre>\n\n\n\n<p class=\"has-normal-font-size\" style=\"text-indent:.2in;\"><strong>Explanation:<\/strong><\/p>\n\n<p class=\"has-normal-font-size\" style=\"text-indent:.2in;\">Here array is created dynamically Thread_object[count_thread] by reading the CPU thread count. The process is later split equally and assigned to the thread and the process is started by start() function. <\/p>\n\n&nbsp;<p class=\"has-medium-font-size\"><strong>Std::cout Vs qDebug()<\/strong><\/p>\n\n<p class=\"has-normal-font-size\" style=\"text-indent:.2in;\">std::cout and qDebug() are both used for outputting information in C++, but they serve different purposes. std::cout is a standard C++ stream used for printing messages to the console and is independent of any framework. It&#8217;s typically used in general-purpose C++ programming for logging or debugging but lacks advanced features like formatting or categorization without external libraries.<\/p>\n\n<p class=\"has-normal-font-size\" style=\"text-indent:.2in;\">qDebug(), on the other hand, is part of the Qt framework and is designed for logging and debugging Qt applications. It provides richer functionality, such as automatic formatting of Qt types (e.g., QString, QList), output to different logging systems, and the ability to control verbosity levels. Additionally, qDebug() outputs can be disabled in release builds, making it more flexible for debugging in Qt environments.<\/p>\n\n<p class=\"has-normal-font-size\" style=\"text-indent:.2in;\">From the image below, we can see the print is joined inspite of using std::endl.<\/p>\n\n\n\n<div class=\"wp-block-columns is-layout-flex wp-container-core-columns-is-layout-28f84493 wp-block-columns-is-layout-flex\">\n<div class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\">\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"738\" height=\"441\" src=\"https:\/\/blog.vishnumuthu.com\/wp-content\/uploads\/2024\/09\/qt_thread_1.png\" alt=\"\" class=\"wp-image-646\" srcset=\"https:\/\/blog.vishnumuthu.com\/wp-content\/uploads\/2024\/09\/qt_thread_1.png 738w, https:\/\/blog.vishnumuthu.com\/wp-content\/uploads\/2024\/09\/qt_thread_1-300x179.png 300w\" sizes=\"auto, (max-width: 738px) 100vw, 738px\" \/><figcaption class=\"wp-element-caption\">qDebug() output<\/figcaption><\/figure>\n<\/div>\n\n\n\n<div class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\">\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"658\" height=\"383\" src=\"https:\/\/blog.vishnumuthu.com\/wp-content\/uploads\/2024\/09\/qt_thread_2-1.png\" alt=\"\" class=\"wp-image-648\" srcset=\"https:\/\/blog.vishnumuthu.com\/wp-content\/uploads\/2024\/09\/qt_thread_2-1.png 658w, https:\/\/blog.vishnumuthu.com\/wp-content\/uploads\/2024\/09\/qt_thread_2-1-300x175.png 300w\" sizes=\"auto, (max-width: 658px) 100vw, 658px\" \/><figcaption class=\"wp-element-caption\">std::cout output<\/figcaption><\/figure>\n<\/div>\n<\/div>\n\n\n\n&nbsp;<p class=\"has-medium-font-size\"><strong>QT Signal \u2013 Slot:<\/strong><\/p>\n\n<p class=\"has-normal-font-size\" style=\"text-indent:.2in;\">Qt&#8217;s signal-slot mechanism is a powerful feature for communication between objects in Qt applications. It allows objects to send and receive messages, enabling loose coupling and event-driven programming. A signal is emitted when a particular event occurs, and a slot is a function designed to respond to that signal. Multiple slots can be connected to a single signal, and one signal can be connected to multiple slots, even across different threads. This system replaces traditional callbacks and enhances readability, scalability, and maintainability, making it easier to build interactive, event-driven applications in Qt.<\/p>\n\n&nbsp;<p class=\"has-medium-font-size\"><strong>Create Thread as QVector:<\/strong><\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>\/\/thread_call.h\nclass thread_call : public QObject\n{\n    Q_OBJECT\npublic:\n    explicit thread_call(QObject *parent = nullptr);\n\n    QVector&lt;Thread_object *&gt; obj;\n\n    void split_thread();\n\npublic slots:\n    void read_processed(int data);\n\nsignals:\n\nprivate:\n    int thread_count;\n};\n\n\/\/ thread_call.cpp\nthread_call::thread_call(QObject *parent)\n    : QObject{parent}\n{\n    QThread cpuInfo; \/\/get CPU info\n    thread_count = cpuInfo.idealThreadCount();\n    for(int i = 0; i &lt; thread_count; i++)\n    {\n        Thread_object*create_process = new Thread_object; \/\/ Thread as QVector\n        obj.append(create_process);\n        connect(create_process, &amp;Thread_object::send_finished,this, &amp;thread_call::read_processed);\n    }\n}\nvoid thread_call::split_thread()\n{\n    int index_start = 0, index_end = 99;\n    int avg_count = (index_end - index_start) \/ thread_count;\n    std::cout &lt;&lt; \"Avg: \" &lt;&lt; avg_count &lt;&lt; std::endl;\n\n    for(int i = 0; i &lt; thread_count; i++)\n    {\n        if(i == 0) \/\/ Start\n        {\n            obj.at(i)-&gt;get_limit(index_start, avg_count);\n            obj.at(i)-&gt;start();\n        }\n        else if(i == thread_count - 1) \/\/ End\n        {\n            obj.at(i)-&gt;get_limit((avg_count * i) + 1, index_end);\n            obj.at(i)-&gt;start();\n        }\n        else \/\/ Middle\n        {\n            obj.at(i)-&gt;get_limit((avg_count * i) + 1, avg_count * (i + 1));\n            obj.at(i)-&gt;start();\n        }\n    }\n}\nvoid thread_call::read_processed(int data)\n{\n    qDebug() &lt;&lt; data;\n}\n<\/code><\/pre>\n\n\n\n<p class=\"has-normal-font-size\" style=\"text-indent:.2in;\">Comment all and change the main.cpp to,<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>\/\/ main.cpp\n    thread_call call;\n    call.split_thread();\n<\/code><\/pre>\n\n\n\n<p class=\"has-normal-font-size\" style=\"text-indent:.2in;\"><strong>Explanation:<\/strong><\/p>\n\n<p class=\"has-normal-font-size\" style=\"text-indent:.2in;\">Here in Thread_call constructor, QVector is created and inserted with Thread_object object. A signal slot is connected between each Thread_object and the Thread_call method. The Thread_call process is later split equally and assigned to the thread object and the process is started by start() function. <\/p>\n\n&nbsp;&nbsp;\n\n\n\n<div class=\"wp-block-buttons alignwide is-content-justification-center is-layout-flex wp-container-core-buttons-is-layout-a89b3969 wp-block-buttons-is-layout-flex\">\n<div class=\"wp-block-button\"><a class=\"wp-block-button__link wp-element-button\" href=\"https:\/\/blog.vishnumuthu.com\/index.php\/2024\/09\/08\/simple-working-of-imgui-implot-and-udp-socket\/\">Next post: Simple working of Imgui, Implot and UDP Socket<\/a><\/div>\n<\/div>\n","protected":false},"excerpt":{"rendered":"<p>&nbsp; A simple understanding of qthread The Example qt_qthread github link, Create a simple working for qt qthread with cmake to show the working of Multi-thread array. * The example shows the reading the number of thread count * The example shows creating multiple thread using dynamic array object and Qvector with signal\/slot. * The [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":660,"comment_status":"open","ping_status":"open","sticky":false,"template":"wp-custom-template-template-cpp","format":"standard","meta":{"footnotes":""},"categories":[133],"tags":[137,134,138],"class_list":["post-643","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-cpp","tag-cmake","tag-cpp","tag-qthread"],"_links":{"self":[{"href":"https:\/\/blog.vishnumuthu.com\/index.php\/wp-json\/wp\/v2\/posts\/643","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/blog.vishnumuthu.com\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blog.vishnumuthu.com\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blog.vishnumuthu.com\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.vishnumuthu.com\/index.php\/wp-json\/wp\/v2\/comments?post=643"}],"version-history":[{"count":6,"href":"https:\/\/blog.vishnumuthu.com\/index.php\/wp-json\/wp\/v2\/posts\/643\/revisions"}],"predecessor-version":[{"id":645,"href":"https:\/\/blog.vishnumuthu.com\/index.php\/wp-json\/wp\/v2\/posts\/643\/revisions\/645"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/blog.vishnumuthu.com\/index.php\/wp-json\/wp\/v2\/media\/660"}],"wp:attachment":[{"href":"https:\/\/blog.vishnumuthu.com\/index.php\/wp-json\/wp\/v2\/media?parent=643"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.vishnumuthu.com\/index.php\/wp-json\/wp\/v2\/categories?post=643"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.vishnumuthu.com\/index.php\/wp-json\/wp\/v2\/tags?post=643"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}