{"id":5401,"date":"2022-06-18T00:01:15","date_gmt":"2022-06-18T07:01:15","guid":{"rendered":"https:\/\/c-for-dummies.com\/blog\/?p=5401"},"modified":"2022-06-11T08:36:04","modified_gmt":"2022-06-11T15:36:04","slug":"the-thread-must-die","status":"publish","type":"post","link":"https:\/\/c-for-dummies.com\/blog\/?p=5401","title":{"rendered":"The Thread Must Die!"},"content":{"rendered":"<p>A thread ends in one of three ways: natural causes, an early exit, or sudden death. Yes, it&#8217;s exciting, but no more than any aspect of programming.<br \/>\n<!--more--><br \/>\nI suppose the normal way for a thread to die is along with its parent program. Because the thread is part of the same overall process, when the main program terminates so do any spawned threads.<\/p>\n<p>A thread can also terminate early, as was demonstrated in <a href=\"https:\/\/c-for-dummies.com\/blog\/?p=5393\">last week&#8217;s Lesson<\/a>. This trick is used to capture a thread&#8217;s return value.<\/p>\n<p>Another way to rub out a thread is to kill it off. The <em>pthread_cancel()<\/em> function handles the assassination. Its sole argument is the <em>pthread_t<\/em> value of a launched and running thread. Poof! The thread is gone.<\/p>\n<p>The following code launches a thread that runs an endless loop. The main program pauses twice: once just because and a second time to quit.<\/p>\n<h3><a href=\"https:\/\/github.com\/dangookin\/C-For-Dummies-Blog\/blob\/master\/2022_06_18-Lesson-a.c\" rel=\"noopener\" target=\"_blank\">2022_06_18-Lesson-a.c<\/a><\/h3>\n<pre class=\"screen\">\r\n#include &lt;stdio.h&gt;\r\n#include &lt;stdlib.h&gt;\r\n#include &lt;unistd.h&gt;\r\n#include &lt;pthread.h&gt;\r\n\r\nvoid *eternal(void *p)\r\n{\r\n    for( ;; )\r\n    {\r\n        printf(\"On I go...\\n\");\r\n        sleep(1);\r\n    }\r\n}\r\n\r\nint main()\r\n{\r\n    pthread_t thd;\r\n    int r;\r\n\r\n    puts(\"Launching endless thread...\");\r\n    <span class=\"comments\">\/* spawn the new thread *\/<\/span>\r\n    r = pthread_create( &amp;thd, NULL, eternal, NULL);\r\n    if( r!=0 )\r\n    {\r\n        perror(\"Thread\");\r\n        exit(1);\r\n    }\r\n    \r\n    puts(\"Press Enter just because\");\r\n    getchar();\r\n\r\n    puts(\"Press Enter to quit\");\r\n    getchar();\r\n\r\n    return(0);\r\n}<\/pre>\n<p>Here&#8217;s a sample run, where I press the Enter key (twice), but wait until the thread first spews out its text:<\/p>\n<p><code>Launching endless thread...<br \/>\nPress Enter just because<br \/>\nOn I go...<br \/>\nOn I go...<br \/>\nOn I go...<\/p>\n<p>Press Enter to quit<br \/>\nOn I go...<br \/>\nOn I go...<\/code><\/p>\n<p>The following update to the code adds the <em>pthread_cancel()<\/em> function to terminate the thread after the first Enter key prompt:<\/p>\n<h3><a href=\"https:\/\/github.com\/dangookin\/C-For-Dummies-Blog\/blob\/master\/2022_06_18-Lesson-b.c\" rel=\"noopener\" target=\"_blank\">2022_06_18-Lesson-b.c<\/a><\/h3>\n<pre class=\"screen\">\r\n#include &lt;stdio.h&gt;\r\n#include &lt;stdlib.h&gt;\r\n#include &lt;unistd.h&gt;\r\n#include &lt;pthread.h&gt;\r\n\r\nvoid *eternal(void *p)\r\n{\r\n    for( ;; )\r\n    {\r\n        printf(\"On I go...\\n\");\r\n        sleep(1);\r\n    }\r\n}\r\n\r\nint main()\r\n{\r\n    pthread_t thd;\r\n    int r;\r\n\r\n    puts(\"Launching endless thread...\");\r\n    <span class=\"comments\">\/* spawn the new thread *\/<\/span>\r\n    r = pthread_create( &amp;thd, NULL, eternal, NULL);\r\n    if( r!=0 )\r\n    {\r\n        perror(\"Thread\");\r\n        exit(1);\r\n    }\r\n    \r\n    puts(\"Press Enter to kill the thread\");\r\n    getchar();\r\n    pthread_cancel(thd);\r\n    puts(\"Thread terminated\");\r\n\r\n    puts(\"Press Enter to quit\");\r\n    getchar();\r\n\r\n    return(0);\r\n}<\/pre>\n<p>The first prompt&#8217;s text (Line 29) is updated to direct the user to press Enter to kill the thread. The <em>pthread_cancel()<\/em> function removes it, followed by output confirming that the thread is dead. Here&#8217;s a sample run:<\/p>\n<p><code>Launching endless thread...<br \/>\nPress Enter to kill the thread<br \/>\nOn I go...<br \/>\nOn I go...<br \/>\nOn I go...<br \/>\nOn I go...<\/p>\n<p>Thread terminated<br \/>\nPress Enter to quit<\/code><\/p>\n<p>It&#8217;s important that you not use <em>pthread_cancel()<\/em> haphazardly. You don&#8217;t want to suddenly cancel a thread in the middle of something, which may create an unstable or undesirable condition.<\/p>\n<p>To protect a thread from cancelation, refer to the <em>pthread_setcancelstate()<\/em> and <em>pthread_setcanceltype()<\/em> functions. You can also use the <em>pthread_testcancel()<\/em> function to insert a safe cancellation point within a thread&#8217;s code.<\/p>\n<p>A good web page for further research on the topic of multithreaded programming in C is found here:<a href=\"https:\/\/docs.oracle.com\/cd\/E19455-01\/806-5257\/index.html\" rel=\"noopener\" target=\"_blank\">Multithreaded Programming Guide<\/a> from Oracle.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Like any code, it&#8217;s possible for a thread to run endlessly. <a href=\"https:\/\/c-for-dummies.com\/blog\/?p=5401\">Continue reading <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[2],"tags":[],"class_list":["post-5401","post","type-post","status-publish","format-standard","hentry","category-main"],"_links":{"self":[{"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/5401","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=5401"}],"version-history":[{"count":3,"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/5401\/revisions"}],"predecessor-version":[{"id":5416,"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/5401\/revisions\/5416"}],"wp:attachment":[{"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=5401"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=5401"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=5401"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}