{"id":472,"date":"2009-09-30T17:17:55","date_gmt":"2009-09-30T23:17:55","guid":{"rendered":"http:\/\/thesmithfam.org\/blog\/?p=472"},"modified":"2019-08-12T07:15:46","modified_gmt":"2019-08-12T13:15:46","slug":"lock-free-multi-threading-in-qt","status":"publish","type":"post","link":"https:\/\/thesmithfam.org\/blog\/2009\/09\/30\/lock-free-multi-threading-in-qt\/","title":{"rendered":"Lock Free Multithreading in Qt"},"content":{"rendered":"<p>If multithreading is challenging to get right in your applications, then lock-free multithreading is <a href=\"http:\/\/labs.trolltech.com\/blogs\/2008\/10\/22\/a-never-ending-struggle\/\">down-right killer<\/a>.<\/p>\n<p>This article won&#8217;t go into detail about <a href=\"http:\/\/en.wikipedia.org\/wiki\/Non-blocking_synchronization\">lock-free algorithms<\/a>, but instead I will offer a &#8220;poor man&#8217;s&#8221; method for crossing thread boundaries in Qt without using locks (no mutexes, no semaphores). At least, <b>your<\/b> code won&#8217;t have any locks. More on that later.<\/p>\n<p>For years, Qt has sported an easy-to-use threading library, based around a class called <b>QThread<\/b>. As of Qt4, you can use <b>QThread<\/b> to start your own event loops. This might sound somewhat uninteresting at first, but it means you can have your own signals and slots outside the main thread. The Trolls created a new way to connect signals to slots such that signals can actually <b>cross<\/b> thread boundaries. I can now emit a signal in one thread and receive it in a slot in a different thread. This is hugely useful when you want to, for example, integrate a blocking-happy library into your application. Here&#8217;s what I&#8217;m talking about in pictures:<\/p>\n<p><img decoding=\"async\" src=\"\/images\/qt-multithreading-1.png\" \/><\/p>\n<style>\npre { font-size: 10pt; border: 2px solid #016; padding: 5px; color: white; background: #333; }\n<\/style>\n<p>Signals can arrive at any time from the threads, just like any other signal, and the code in the main event loop doesn&#8217;t know anything about multi-threading, locks, or condition variables.<\/p>\n<p><b>An Example<\/b><\/p>\n<p>Let&#8217;s say you want to integrate with a third-party library that blocks when you call its functions. Of course, if you call this library from your main event loop, your application will freeze while it&#8217;s running. That would be annoying, and you can give your users a better experience than that. Let&#8217;s wrap that library in a <b>QThread<\/b>. First, you need to declare a new QThread subclass, like this:<\/p>\n<pre>class MyLibraryWrapper : public QThread\r\n{\r\nQ_OBJECT\r\npublic:\r\n    MyLibraryWrapper();\r\nprotected:\r\n   void run();\r\nsignals:\r\n   void done(const QString &results);\r\nprivate slots:\r\n   void doTheWork();\r\n};<\/pre>\n<p>The <b>run()<\/b> method is called automagically by Qt when the caller calls <b>start()<\/b> on your thread. This is similar to how Java&#8217;s <b>Thread<\/b> class works.<\/p>\n<p>The <b>done()<\/b> signal is how the object tells you it is finished with its work. It emits a <b>QString<\/b> in this example, but it can emit anything you want (note that if you want to emit non-primitive or non-Qt types, you need to use the <b>Q_DECLARE_METATYPE()<\/b> macro, which we won&#8217;t go into in this article).<\/p>\n<p>The <b>doTheWork()<\/b> slot is there to actually do the blocking work. It has to be a slot so we can put it to work <b>after<\/b> our event loop starts up (which you&#8217;ll see in a minute).<\/p>\n<p>Now for the implementation of <b>MyLibraryWrapper<\/b>:<\/p>\n<pre>\r\nMyLibraryWrapper::MyLibraryWrapper() : QThread()\r\n{\r\n  \/\/ We have to do this to make sure our thread has the\r\n  \/\/ <a href=\"http:\/\/doc.trolltech.com\/4.5\/qobject.html#moveToThread\">correct affinity.<\/a>\r\n  moveToThread(this);\r\n\r\n  \/\/ This will do nothing until the user calls start().\r\n}\r\n\r\nvoid MyLibraryWrapper::run()\r\n{\r\n  \/\/ This schedules the doTheWork() function\r\n  \/\/ to run just after our event loop starts up\r\n  QTimer::singleShot(0, this, SLOT(doTheWork()));\r\n\r\n  \/\/ This starts the event loop. Note that\r\n  \/\/ exec() does not return until the\r\n  \/\/ event loop is stopped.\r\n  exec();    \r\n}\r\n\r\nvoid MyLibraryWrapper::doTheWork()\r\n{\r\n  \/\/ Do the heavy-duty blocking stuff here\r\n  \/\/ (simulated by a 5 second sleep for\r\n  \/\/ this example)\r\n  sleep(5);\r\n\r\n  \/\/ When you're done, emit the results:\r\n  emit done(\"First job's finished.\");\r\n  \r\n  \/\/ And some more sleeping for fun\r\n  sleep(3)\r\n  emit done(\"Second job's finished.\");\r\n\r\n  \/\/ ...\r\n}\r\n<\/pre>\n<p>To actually use this new class, all you have to do is instantiate it in your main event loop and connect it to a slot. Here&#8217;s an example. Let&#8217;s say you have a <b>QMainWindow<\/b> called <b>MyMainWindow<\/b>. This is how you would set it up as a result of a user button click:<\/p>\n<pre>\r\nvoid MyMainWindow::on_someButton_clicked()\r\n{\r\n  MyLibraryWrapper *wrapper = new MyLibraryWrapper();\r\n\r\n  \/\/ This is the magic that tells the wrapper to\r\n  \/\/ notify us when it's done. We use a QueuedConnection\r\n  \/\/ to make sure Qt delivers the signal in a thread\r\n  \/\/ safe manner\r\n  connect(wrapper, SIGNAL(done(QString)),\r\n          this, SLOT(wrapperDone(QString)),\r\n          Qt::QueuedConnection);\r\n\r\n  \/\/ This kicks off the wrapper's event loop by causing its\r\n  \/\/ run() method to be called\r\n  wrapper->start();\r\n}\r\n\r\nvoid MyMainWindow::wrapperDone(const QString &results)\r\n{\r\n  \/\/ The wrapper is now done with its long, blocking\r\n  \/\/ operation, and we didn't freeze the application.\r\n  \/\/ Yay for us!\r\n\r\n  qDebug() &lt;&lt; \"Here are your results:\" &lt;&lt; results;\r\n}\r\n<\/pre>\n<p><b>Conclusion<\/b><\/p>\n<p>Notice that none of our code uses a semaphore, condition variable, or mutex? Using <b>QThread<\/b> makes it super easy to wrap up libraries that need to block the event loop in a way that is transparent to the caller.<\/p>\n<p>I claimed earlier that this code would be &#8220;lock free&#8221;. I can&#8217;t actually claim that is 100% true. I don&#8217;t know for sure, but I imagine that Qt&#8217;s internal event loop code does indeed use locks to pass signals between event loops. All I know for sure is that <b>this<\/b> code crosses thread boundaries without any locks.<\/p>\n<p>Stay tuned for another article that shows how you can call setter functions on your threaded objects without any need for locks.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>If multithreading is challenging to get right in your applications, then lock-free multithreading is down-right killer. This article won&#8217;t go into detail about lock-free algorithms, but instead I will offer a &#8220;poor man&#8217;s&#8221; method for crossing thread boundaries in Qt without using locks (no mutexes, no semaphores). At least, your code won&#8217;t have any locks. [&hellip;]<\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[2],"tags":[],"class_list":["post-472","post","type-post","status-publish","format-standard","hentry","category-code-and-cruft"],"_links":{"self":[{"href":"https:\/\/thesmithfam.org\/blog\/wp-json\/wp\/v2\/posts\/472","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/thesmithfam.org\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/thesmithfam.org\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/thesmithfam.org\/blog\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/thesmithfam.org\/blog\/wp-json\/wp\/v2\/comments?post=472"}],"version-history":[{"count":34,"href":"https:\/\/thesmithfam.org\/blog\/wp-json\/wp\/v2\/posts\/472\/revisions"}],"predecessor-version":[{"id":1532,"href":"https:\/\/thesmithfam.org\/blog\/wp-json\/wp\/v2\/posts\/472\/revisions\/1532"}],"wp:attachment":[{"href":"https:\/\/thesmithfam.org\/blog\/wp-json\/wp\/v2\/media?parent=472"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/thesmithfam.org\/blog\/wp-json\/wp\/v2\/categories?post=472"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/thesmithfam.org\/blog\/wp-json\/wp\/v2\/tags?post=472"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}