{"id":862,"date":"2019-01-28T19:02:16","date_gmt":"2019-01-28T19:02:16","guid":{"rendered":"http:\/\/www.yazilimperver.com\/?p=862"},"modified":"2019-03-08T19:45:26","modified_gmt":"2019-03-08T19:45:26","slug":"english-weekly-c-8-stdthread-ii","status":"publish","type":"post","link":"https:\/\/www.yazilimperver.com\/index.php\/2019\/01\/28\/english-weekly-c-8-stdthread-ii\/","title":{"rendered":"Haftal\u0131k C++ 8- std::thread (II)"},"content":{"rendered":"<p>Evet, thread ile ilgili yaz\u0131lar\u0131m\u0131za devam etme zaman\u0131 geldi. Bu yaz\u0131mda, sizlere thread k\u00fct\u00fcphanesi i\u00e7erisinde bulunan ve C++ kullanarak multithreaded yaz\u0131l\u0131m geli\u015ftirme esnas\u0131nda, size faydas\u0131 dokunaca\u011f\u0131n\u0131 d\u00fc\u015f\u00fcnd\u00fc\u011f\u00fcm yap\u0131lardan bahsedece\u011fim. Thread k\u00fct\u00fcphanesi ve ilgili girizgah\u0131 bir \u00f6nceki yaz\u0131mda yapm\u0131\u015ft\u0131m, e\u011fer onu okumad\u0131ysan\u0131z, mutlaka okuman\u0131z\u0131 \u00f6neririm. A\u015fa\u011f\u0131da ilgili yaz\u0131ma ve serinin di\u011fer yaz\u0131lar\u0131na ili\u015fkin ba\u011flant\u0131lar\u0131 bulabilirsiniz:<\/p>\n<p><strong><span style=\"color: #008000;\"><a style=\"color: #008000;\" href=\"http:\/\/www.yazilimperver.com\/index.php\/2018\/12\/31\/english-weekly-c-7-stdthread\/\">Haftal\u0131k C++ 7- std::thread (I)<\/a><\/span><\/strong><\/p>\n<p><strong><span style=\"color: #008000;\"><a style=\"color: #008000;\" href=\"http:\/\/www.yazilimperver.com\/index.php\/2019\/01\/28\/english-weekly-c-8-stdthread-ii\/\">Haftal\u0131k C++ 8- std::thread (II)<\/a><\/span><\/strong><\/p>\n<p><strong><span style=\"color: #008000;\"><a style=\"color: #008000;\" href=\"http:\/\/www.yazilimperver.com\/index.php\/2019\/03\/08\/haftalik-c-10-stdthread-iii\/\">Haftal\u0131k C++ 10- std::thread (III)<\/a><\/span><\/strong><\/p>\n<p>Asl\u0131nda, ilk etapta, senkronizasyon yap\u0131lar\u0131ndan da bahsetmeyi planl\u0131yordum fakat daha sonra bu yaz\u0131y\u0131 sadece yard\u0131mc\u0131 yap\u0131larak ay\u0131r\u0131p, senkronizasyon yap\u0131lar\u0131 i\u00e7in ayr\u0131 bir yaz\u0131 yazmaya karar verdim. \u00d6b\u00fcr t\u00fcrl\u00fc, yaz\u0131y\u0131 takip etmek ve b\u00fct\u00fcnl\u00fc\u011f\u00fc korumak ger\u00e7ekten zor olacakt\u0131. Bu yaz\u0131mda sizlere aktaraca\u011f\u0131m konular ise: <em>async, futures, promises, packaged_tasks<\/em>\u00a0ve son olarak <em>atomics <\/em>veri yap\u0131lar\u0131. Evet hadi o zaman, ba\u015flayal\u0131m.<\/p>\n<h2><strong><span style=\"color: #0000ff;\">std::async:<\/span><\/strong><\/h2>\n<p><em>async &#8216;&lt;<\/em>future&gt;<em>&#8216;\u00a0<\/em>k\u00fct\u00fcphanesi taraf\u0131ndan farkl\u0131 prototipleri sunulan, ba\u011f\u0131ms\u0131z \u015fablon bir fonksiyondur (template function). Bu fonksiyonlar, parametre olarak ge\u00e7irilen fonksiyonlar\u0131 asenkron olarak ko\u015fturup (bu genelde ayr\u0131 bir thread olu\u015fturularak ve ko\u015fturulmas\u0131 ile sa\u011flan\u0131r, ama geli\u015ftirici bundan soyutlan\u0131r), sonucu ve ko\u015fum durumunu <em>std::future<\/em> nesnesi (birazdan a\u00e7\u0131klayaca\u011f\u0131m) olarak d\u00f6nerler. Asl\u0131nda g\u00f6rebilece\u011finiz \u00fczere, bu yap\u0131, basit thread kullan\u0131m ihtiya\u00e7lar\u0131n\u0131z\u0131 gidermek i\u00e7in geli\u015ftirilmi\u015f bir \u00fcst seviye yap\u0131 olarak de\u011ferlendirilebilir. Di\u011fer bir deyi\u015fle, bu metot kullanarak yapaca\u011f\u0131n\u0131z herhangi bir i\u015fi Thread k\u00fct\u00fcphanesinin di\u011fer yap\u0131lar\u0131n\u0131 da kullanarak yapabilirsiniz.<\/p>\n<p>Tahmin edebilece\u011finiz \u00fczere, bu metotlara, fonksiyon, fonksiyon i\u015faret\u00e7isi, fonksiyon nesnesi ve lambda fonksiyonlar\u0131n\u0131, ihtiya\u00e7 duyduklar\u0131 parametreleri ile birlikte ge\u00e7irebilirsiniz. Bu parametreleri de <em>async()<\/em> metotlar\u0131na parametre olarak ge\u00e7irebilirsiniz. \u0130lgili metodun dok\u00fcmantasyonun verilen a\u015fa\u011f\u0131daki \u00f6rnek kod, asl\u0131nda bu kullan\u0131mlar\u0131 g\u00fczel bir \u015fekilde \u00f6zetliyor:<\/p>\n<pre class=\"lang:c++ decode:true\">#include &lt;iostream&gt;\r\n#include &lt;vector&gt;\r\n#include &lt;algorithm&gt;\r\n#include &lt;numeric&gt;\r\n#include &lt;future&gt;\r\n \r\ntemplate &lt;typename RandomIt&gt;\r\nint parallel_sum(RandomIt beg, RandomIt end)\r\n{\r\n    auto len = end - beg;\r\n    if (len &lt; 1000)\r\n        return std::accumulate(beg, end, 0);\r\n \r\n    RandomIt mid = beg + len\/2;\r\n    auto handle = std::async(std::launch::async,\r\n                             parallel_sum&lt;RandomIt&gt;, mid, end);\r\n    int sum = parallel_sum(beg, mid);\r\n    return sum + handle.get();\r\n}\r\n \r\nint main()\r\n{\r\n    std::vector&lt;int&gt; v(10000, 1);\r\n    std::cout &lt;&lt; \"The sum is \" &lt;&lt; parallel_sum(v.begin(), v.end()) &lt;&lt; '\\n';\r\n}<\/pre>\n<p>Bu fonksiyon ve parametreler yan\u0131nda async metodu, bir de \u00e7al\u0131\u015ft\u0131rma politikas\u0131 denile ve \u00fc\u00e7 farkl\u0131 de\u011fer alan bir parametre de kabul etmektedir:<\/p>\n<ul>\n<li><strong>std::launch::async<\/strong>\n<ul>\n<li>Verilen i\u015f asenkron olarak, farkl\u0131 bir thread i\u00e7erisinde ko\u015fturulur.<\/li>\n<\/ul>\n<\/li>\n<li><strong>std::launch::deferred<\/strong>\n<ul>\n<li>Verilen i\u015f d\u00f6n\u00fclen std::future nesnesinin get() metodu \u00e7a\u011fr\u0131ld\u0131\u011f\u0131nda ko\u015fturulur.<\/li>\n<\/ul>\n<\/li>\n<li><strong>std::launch::async |\u00a0std::launch::deferred<\/strong>\n<ul>\n<li><strong>Varsay\u0131lan parametre<\/strong> budur. Bu parametre de\u011feri ge\u00e7irildi\u011fi durumda, sistemin mevcut y\u00fck\u00fcne g\u00f6re: senkron ya da asenkron \u00e7a\u011fr\u0131labilir. Geli\u015ftiricinin bunun \u00fczerinde kontrol\u00fc yoktur.<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<p><em>async()<\/em> kullan\u0131m\u0131n\u0131 daha iyi anlaman\u0131za yard\u0131mc\u0131 olaca\u011f\u0131n\u0131 d\u00fc\u015f\u00fcnd\u00fc\u011f\u00fcm bir \u00f6rnek kod daha ekliyorum (al\u0131nt\u0131lad\u0131\u011f\u0131m kayna\u011fa da referanslardan ula\u015fabilirsiniz):<\/p>\n<pre class=\"lang:c++ decode:true\">#include &lt;string&gt;\r\n#include &lt;chrono&gt;\r\n#include &lt;thread&gt;\r\n#include &lt;future&gt;\r\n \r\nusing namespace std::chrono;\r\n \r\nstd::string fetchDataFromDB(std::string recvdData)\r\n{\r\n\t\/\/ Bu metodun tamamlanmas\u0131n\u0131n 5 saniye s\u00fcreci\u011fini garantile\r\n\tstd::this_thread::sleep_for(seconds(5));\r\n \r\n\t\/\/ Bu s\u0131rada veri taban\u0131 ba\u011flant\u0131s\u0131 ya da veri odakl\u0131 i\u015fleri halledebiliriz\r\n\treturn \"DB_\" + recvdData;\r\n}\r\n \r\nstd::string fetchDataFromFile(std::string recvdData)\r\n{\r\n         \/\/ Bu metodun tamamlanmas\u0131n\u0131n 5 saniye s\u00fcreci\u011fini garantile\r\n\tstd::this_thread::sleep_for(seconds(5));\r\n \r\n\t\/\/ Bu s\u0131rada veri odakl\u0131 i\u015fleri halledebiliriz\r\n\treturn \"File_\" + recvdData;\r\n}\r\n \r\nint main()\r\n{\r\n\t\/\/ Ba\u015flang\u0131\u00e7 zaman\u0131n\u0131 tutual\u0131m\r\n\tsystem_clock::time_point start = system_clock::now();\r\n \r\n        \/\/ A\u015fa\u011f\u0131daki kullan\u0131mda toplam s\u00fcreyi 5 saniyeye indiriyoruz\r\n\tstd::future&lt;std::string&gt; resultFromDB = std::async(std::launch::async, fetchDataFromDB, \"Data\");\r\n        \r\n        \/\/ A\u015fa\u011f\u0131daki kullan\u0131mda ise 10 sn bir s\u00fcre ge\u00e7iyor\r\n        \/\/ std::string dbData = fetchDataFromDB(\"Data\");\r\n\r\n\t\/\/ Dosyadan veriyi \u00e7ekelim\r\n\tstd::string fileData = fetchDataFromFile(\"Data\");\r\n \r\n\t\/\/ Veri taban\u0131n veriyi \u00e7ekelim\r\n\t\/\/ future&lt;std::string&gt; object nesnesi haz\u0131r olana kadar bloklar.\r\n\tstd::string dbData = resultFromDB.get();\r\n \r\n\t\/\/ Biti\u015f zaman\u0131n\u0131 alal\u0131m\r\n\tauto end = system_clock::now();\r\n \r\n\tauto diff = duration_cast &lt; std::chrono::seconds &gt; (end - start).count();\r\n\tstd::cout &lt;&lt; \"Total Time Taken = \" &lt;&lt; diff &lt;&lt; \" Seconds\" &lt;&lt; std::endl;\r\n \r\n\t\/\/ Verileri birle\u015ftirelim\r\n\tstd::string data = dbData + \" :: \" + fileData;\r\n \r\n\t\/\/ Birle\u015ftirilmi\u015f veriyi basal\u0131m\r\n\tstd::cout &lt;&lt; \"Data = \" &lt;&lt; data &lt;&lt; std::endl;\r\n \r\n\treturn 0;\r\n}<\/pre>\n<p>Bu arada, yukar\u0131da verdi\u011fim \u00f6rnekte dikkat etmenizi istedi\u011fim nokta <em>std::future<\/em> nesnesine ili\u015fkin get() API&#8217;sinin \u00e7a\u011fr\u0131ld\u0131\u011f\u0131 zaman mevcut thread&#8217;i verilen i\u015f tamamlan\u0131ncaya kadar bloklamas\u0131d\u0131r. Bunun yan\u0131nda, <em>std::async()<\/em> metodundan d\u00f6n\u00fclen <em>std::future<\/em> nesnesinin y\u0131k\u0131c\u0131s\u0131 \u00e7a\u011fr\u0131ld\u0131\u011f\u0131nda da, benzer \u015fekilde mevcut thread bloklan\u0131r. A\u015fa\u011f\u0131da buna ili\u015fkin bir kullan\u0131m g\u00f6sterdim:<\/p>\n<pre class=\"lang:c++ decode:true \">\/\/ Sample from Scott Meyers' Blog\r\nvoid f()\r\n{\r\n  std::future&lt;void&gt; fut = std::async(std::launch::async, \r\n                                     [] { \/* compute, compute, compute *\/ });\r\n}<\/pre>\n<p>Bunun ile ilgili daha detayl\u0131 bilgilere Scott Meyers&#8217;in sayfas\u0131ndan ula\u015fabilirsiniz:\u00a0<a href=\"http:\/\/scottmeyers.blogspot.com\/2013\/03\/stdfutures-from-stdasync-arent-special.html\"><strong><span style=\"color: #008000;\">Scott&#8217;s blog post<\/span><\/strong><\/a>.<\/p>\n<p>\u015eimdi, std::future&#8217;a bakma zaman\u0131.<\/p>\n<h2><strong><span style=\"color: #0000ff;\">std::future &amp; std::promise:<\/span><\/strong><\/h2>\n<p>C++11 thread k\u00fct\u00fcphanesi ile gelen bir di\u011fer yap\u0131 da <em>std::future<\/em> s\u0131n\u0131f\u0131d\u0131r. Bunun kullanmak i\u00e7in\u00a0&#8216;&lt;future&gt;&#8217; ba\u015fl\u0131k dosyas\u0131n\u0131 kaynak kodunuza eklemeniz gerekiyor. Bu yap\u0131, yukar\u0131da g\u00f6rd\u00fc\u011f\u00fcn\u00fcz gibi <em>async<\/em>() metodu yan\u0131nda <em>std::packaged_task<\/em> ve <em>std::promise<\/em> yap\u0131lar\u0131 ile de kullan\u0131lmaktad\u0131r. Peki ne yapar bu s\u0131n\u0131f? Bu s\u0131n\u0131f\u0131n temel i\u015flevi, k\u0131saca <em>async<\/em>() metodu gibi thread ko\u015fumlar\u0131nda, ilgili de\u011ferlerin d\u00f6n\u00fclmesine sa\u011flamakt\u0131r.<\/p>\n<p>Geleneksel olarak, thread&#8217;ler aras\u0131nda veri payla\u015f\u0131m\u0131n\u0131 ger\u00e7ekle\u015ftirmek i\u00e7in, mutex ve benzeri thread senkronizasyon yap\u0131lar\u0131n\u0131 kullanman\u0131z gerekmektedir. Dahas\u0131, ger\u00e7ekle\u015ftirilen bu i\u015flem sonras\u0131nda, \u00e7a\u011f\u0131ran s\u0131n\u0131f\u0131 haberdar etmek i\u00e7in de\u00a0 <em>std::conditional_variable<\/em> tarz\u0131 yap\u0131lar\u0131 da kullanman\u0131z gerekebiliyor. <em>std::future<\/em>, bu tarz temel ihtiya\u00e7lar\u0131 gidermek i\u00e7in sunulan bir s\u0131n\u0131f. Bu s\u0131n\u0131f, ca\u011fr\u0131lan thread taraf\u0131ndan sa\u011flanacak olan veriyi tutar ve ilgili \u00e7a\u011f\u0131ran buna eri\u015fmesi i\u00e7in gerekli olan alt yap\u0131lar\u0131 geli\u015ftiriciye sunmadan kotar\u0131r. Ne zamanki, \u00e7a\u011f\u0131ran s\u0131n\u0131f <em>std::future<\/em> nesnesine ili\u015fkin <em>get<\/em>() API&#8217;sini \u00e7a\u011f\u0131r\u0131r, o zaman ilgili i\u015f bitene kadar bu thread bloklan\u0131r ve verilen i\u015f bitince de ilgili de\u011fer d\u00f6n\u00fcl\u00fcr.<\/p>\n<p>Bu s\u0131n\u0131fa benzer \u015fekilde, <em>std::promise<\/em> s\u0131n\u0131f\u0131 da asl\u0131nda <em>std::future<\/em> ile d\u00f6n\u00fclecek bir de\u011fer i\u00e7in s\u00f6z olarak kabul edilebilir. Bir di\u011fer deyi\u015fle, her bir <em>std::promise<\/em> nesnesi ile ilintili bir s<em>td::future<\/em> nesnesi bulunur ve bu ilgili de\u011feri \u00e7a\u011f\u0131rana sa\u011flar. Peki <em>std::promise<\/em>&#8216;in buradaki kullan\u0131m\u0131 nedir? <em>std::promise<\/em> nesnesi,<em> std::future<\/em> nesnesi ile birlikte payla\u015ft\u0131\u011f\u0131 verinin, ilgili thread i\u00e7erisinde atanmas\u0131 i\u00e7in gerekli aray\u00fcz sunar. Bu kadar a\u00e7\u0131klaman\u0131n biraz kafa kar\u0131\u015ft\u0131r\u0131c\u0131 olabilece\u011finin fark\u0131nday\u0131m, yine referanslarda verdi\u011fim bir kaynakta buraya koydu\u011fum a\u015fa\u011f\u0131daki fig\u00fcr, bu iki nesne aras\u0131ndaki ili\u015fki ve kullan\u0131mlar\u0131n\u0131 \u00e7ok g\u00fczel \u00f6zetliyor:<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/thispointer.com\/\/wp-content\/uploads\/2015\/06\/promise.png\" alt=\"std::promise and std::future\" \/><\/p>\n<p>Burada <em>std::promise<\/em> nesnesi asl\u0131nda arkada iki thread aras\u0131nda payla\u015f\u0131lacak olan veriyi ifade\/temsil ediyor. <em>std::future<\/em> nesnesi ise bu <em>std::promise<\/em> nesnesi \u00fczerinden d\u00f6n\u00fclecek de\u011feri temsil ediyor. Genel kullan\u0131m\u0131 bakt\u0131\u011f\u0131m\u0131z zaman, ilgili threadi olu\u015fturan, \u00f6ncelikle bir <em>std::promise<\/em> nesnesi olu\u015fturuyor ve buna ilintilendirilmi\u015f bir ya da daha fazla <em>std::future<\/em> nesnesini ediniyor. Daha sonra <em>std::promise<\/em> nesnesini, olu\u015fturaca\u011f\u0131 yeni thread&#8217;e ge\u00e7iriyor ve yeni thread bu nesne \u00fczerinden payla\u015f\u0131lacak olan veriyi at\u0131yor ya da hata durumunu iletiyor. Bu a\u015famada, <em>std::future<\/em> nesneleri \u00fczerinden ilgili d\u00f6n\u00fc\u015f de\u011ferinin atan\u0131p\/atanmad\u0131\u011f\u0131 ya da bir hata olup olmad\u0131\u011f\u0131 sorgulanabilmektedir. A\u015fa\u011f\u0131da bu iki s\u0131n\u0131f\u0131n ili\u015fkisini g\u00f6steren kod par\u00e7as\u0131n\u0131 g\u00f6rebilirsiniz:<\/p>\n<pre class=\"lang:c++ decode:true\">#include &lt;iostream&gt;\r\n#include &lt;thread&gt;\r\n#include &lt;future&gt;\r\n#include &lt;chrono&gt;\r\n\r\nusing namespace std::chrono_literals;\r\n\r\nvoid initialize(std::promise&lt;int&gt; &amp;&amp; promObj)\r\n{\r\n\tstd::cout &lt;&lt; \"Update the value represented by passed promise as 65\" &lt;&lt; '\\n';\r\n\r\n\t\/\/ 5 sn bekletelim\r\n\tstd::this_thread::sleep_for(5s);\r\n\r\n\t\/\/ \u00c7a\u011fr\u0131lan thread d\u00f6n\u00fclecek olan de\u011feri bunun \u00fczerinden iletir. Burada promObj.set_exception() arac\u0131l\u0131\u011f\u0131 ile ya da a\u015fa\u011f\u0131daki\r\n        \/\/ kodu yorumlayarak hata durumu olu\u015fturabilirsiniz\r\n\tpromObj.set_value(65);\t\r\n}\r\n\r\nint main()\r\n{\r\n\tstd::promise&lt;int&gt; promiseObj;\r\n\tstd::future&lt;int&gt; futureObj = promiseObj.get_future();\r\n\r\n\t\/\/ \u0130lgili std::promise nesnesini yeni olu\u015fturulan threade ge\u00e7irelim\r\n\tstd::thread th(initialize, std::move(promiseObj));\r\n\tstd::cout &lt;&lt; \"Wait till task is completed (about 5 seconds)\" &lt;&lt; '\\n';\r\n\r\n\t\/\/ Olu\u015fturulan thread i\u015fini bitene kadar, mevcut thread bloklan\u0131r\r\n\tstd::cout &lt;&lt; futureObj.get() &lt;&lt; std::endl;\r\n\r\n        \/\/ Olu\u015fturulan thread tamamlanana kadar bekle\r\n\tth.join();\r\n\r\n\treturn 0;\r\n}<\/pre>\n<p>E\u011fer\u00fc std::promise nesnesi, ilgili d\u00f6n\u00fc\u015f de\u011feri \u00e7a\u011fr\u0131lmadan silinirse ve de olu\u015fturan thread, std::future nesnesi \u00fczerinden get() API&#8217;sini \u00e7a\u011f\u0131r\u0131r ise, hata durumu olu\u015ftur. Bunun yan\u0131nda bir di\u011fer kullan\u0131m ile birlikte, birden fazla std::promise nesnesini olu\u015fturulan thread&#8217;lere ge\u00e7irerek, \u00e7a\u011f\u0131ran s\u0131n\u0131f bunlara ili\u015fkin std::future nesnelerinden ayr\u0131 ayr\u0131 de\u011ferler elde edilebilir.<\/p>\n<p>Bu iki yap\u0131ya ili\u015fkin g\u00fczel bir a\u00e7\u0131klama da Rainer Grim taraf\u0131ndan <strong><span style=\"color: #008000;\"><a style=\"color: #008000;\" href=\"http:\/\/www.modernescpp.com\/index.php\/promise-and-future\">\u015fu yaz\u0131da<\/a>\u00a0<\/span><\/strong>verilmi\u015f durumda. \u00d6zetleyecek olursak:<\/p>\n<p>std::promise nesnesi:<\/p>\n<ul>\n<li>Bir de\u011fer d\u00f6n\u00fclmesine, hata durumu belirlenmesine ya da bilgilendirme yap\u0131lmas\u0131na olanak sa\u011flar.<\/li>\n<\/ul>\n<p>std::future nesnesi:<\/p>\n<ul>\n<li>std::promise nesnesinden ilgili de\u011ferlerin \u00e7ekilmesine,<\/li>\n<li>std::promise nesnesine, ilgili de\u011ferin haz\u0131r olup\/olmad\u0131\u011f\u0131n\u0131n sorulmas\u0131na,<\/li>\n<li>std::promise nesnesi \u00fczerinden ilgili i\u015flemin bitmesinin beklenmesine,<\/li>\n<li>std::shared_future olu\u015fturulmas\u0131na olanak sa\u011flar.<\/li>\n<\/ul>\n<p>Bu iki yap\u0131n\u0131n kullan\u0131m\u0131na ili\u015fkin bir di\u011fer \u00f6rnek koda g\u00f6z atal\u0131m:<\/p>\n<pre class=\"lang:c++ decode:true\">\/\/ promiseFuture.cpp\r\n\r\n#include &lt;future&gt;\r\n#include &lt;iostream&gt;\r\n#include &lt;thread&gt;\r\n#include &lt;utility&gt;\r\n\r\nvoid product(std::promise&lt;int&gt;&amp;&amp; intPromise, int a, int b)\r\n{\r\n  intPromise.set_value(a*b);\r\n}\r\n\r\nstruct Div\r\n{\r\n  void operator() (std::promise&lt;int&gt;&amp;&amp; intPromise, int a, int b) const \r\n  {\r\n    intPromise.set_value(a\/b);\r\n  }\r\n};\r\n\r\nint main()\r\n{\r\n  int a= 20;\r\n  int b= 10;\r\n\r\n  std::cout &lt;&lt; '\\n';\r\n\r\n  \/\/ \u0130lgili std::promise nesnelerini olu\u015ftural\u0131m\r\n  std::promise&lt;int&gt; prodPromise;\r\n  std::promise&lt;int&gt; divPromise;\r\n\r\n  \/\/ Bunlardan std::future nesnelerini \u00e7ekelim\r\n  std::future&lt;int&gt; prodResult= prodPromise.get_future();\r\n  std::future&lt;int&gt; divResult= divPromise.get_future();\r\n\r\n  \/\/ Hesaplamalar\u0131 ayr\u0131 bir thread'ten \u00e7ekelim\r\n  std::thread prodThread(product,std::move(prodPromise),a,b);\r\n  Div div;\r\n  std::thread divThread(div,std::move(divPromise),a,b);\r\n\r\n  \/\/ Sonu\u00e7lar\u0131 toplayal\u0131m\r\n  std::cout &lt;&lt; \"20*10= \" &lt;&lt; prodResult.get() &lt;&lt; '\\n';\r\n  std::cout &lt;&lt; \"20\/10= \" &lt;&lt; divResult.get() &lt;&lt; '\\n';\r\n\r\n  prodThread.join();  \r\n  divThread.join();\r\n\r\n  std::cout &lt;&lt; '\\n';\r\n}<\/pre>\n<p>std::future s\u0131n\u0131f\u0131na benzer bir di\u011fer s\u0131n\u0131f da std::shared_future s\u0131n\u0131f\u0131. Bu s\u0131n\u0131f\u0131n i\u015flevini galiba en iyi dok\u00fcmantasyonundaki <strong><span style=\"color: #008000;\"><a style=\"color: #008000;\" href=\"https:\/\/en.cppreference.com\/w\/cpp\/thread\/shared_future\">(std::shared_future API dok\u00fcmantasyonu<\/a>)\u00a0<\/span><\/strong>a\u015fa\u011f\u0131daki tan\u0131m \u00f6zetliyor:<\/p>\n<p>std :: shared_future s\u0131n\u0131f \u015fablonu, ger\u00e7ekle\u015ftirilecek olan bir i\u015flemin d\u00f6n\u00fc\u015f de\u011ferine birden fazla thread&#8217;in eri\u015fmesine ve ilgili de\u011ferin i\u00e7in bekletilmesine olanak sa\u011flar. std::future&#8217;dan farkl\u0131 olarak (sadece ta\u015f\u0131narak aktar\u0131labilir), bu nesneler kopyalanabilir ve her bir kopya ayn\u0131 ortak de\u011fere eri\u015firler. Yaln\u0131zca hareketli olan std :: future&#8217;nin aksine (bu nedenle yaln\u0131zca bir \u00f6rnek, herhangi bir zaman uyumsuz sonuca i\u015faret edebilir), std :: shared_future kopyalanabilir ve birden \u00e7ok payla\u015f\u0131lan gelecek nesnesi ayn\u0131 payla\u015f\u0131lan duruma ba\u015fvurabilir. Asl\u0131nda, bir shared_future, std :: condition_variable :: notify_all ()&#8217;a benzer \u015fekilde, ayn\u0131 anda birden fazla i\u015f par\u00e7ac\u0131\u011f\u0131na sinyal vermek i\u00e7in kullan\u0131labilir. Bu s\u0131n\u0131f, bir bak\u0131ma, birden fazla thread&#8217;i, std::condition_variable::notify_all() API&#8217;si gibi, haberdar etmek i\u00e7in kullan\u0131labilir.<\/p>\n<p>Hemen nas\u0131l kullan\u0131ld\u0131\u011f\u0131na \u00f6rnek bir kod \u00fczerinden bakal\u0131m:<\/p>\n<pre class=\"lang:c++ decode:true\">#include &lt;iostream&gt;\r\n#include &lt;future&gt;\r\n#include &lt;chrono&gt;\r\n \r\nint main()\r\n{   \r\n    \/\/ \u0130lgili std::promise nesneleri\r\n    std::promise&lt;void&gt; ready_promise, t1_ready_promise, t2_ready_promise;\r\n\r\n    \/\/ \u0130lgili threadlere payla\u015ft\u0131r\u0131lacak olan std::shared_future nesnesi\r\n    std::shared_future&lt;void&gt; ready_future(ready_promise.get_future());\r\n \r\n    std::chrono::time_point&lt;std::chrono::high_resolution_clock&gt; start;\r\n\r\n    \/\/ Birinci lambda fonksiyonu\r\n    auto fun1 = [&amp;, ready_future]() -&gt; std::chrono::duration&lt;double, std::milli&gt; \r\n    {\r\n        \/\/ ana (main) thread'i haberdar et\r\n        t1_ready_promise.set_value();\r\n\r\n        \/\/ ana (main) thread'ten haber bekliyor\r\n        ready_future.wait(); \r\n        return std::chrono::high_resolution_clock::now() - start;\r\n    };\r\n \r\n    \/\/ \u0130kinci lambda fonksiyonu\r\n    auto fun2 = [&amp;, ready_future]() -&gt; std::chrono::duration&lt;double, std::milli&gt; \r\n    {\r\n        \/\/ ana (main) thread'i haberdar et\r\n        t2_ready_promise.set_value();\r\n        \r\n        \/\/ ana (main) thread'ten haber bekliyor\r\n        ready_future.wait(); \r\n        return std::chrono::high_resolution_clock::now() - start;\r\n    };\r\n \r\n    \/\/ \u0130lgili std::promise nesnelerinden std::future nesnelerini \u00e7ekelim\r\n    auto fut1 = t1_ready_promise.get_future();\r\n    auto fut2 = t2_ready_promise.get_future();\r\n \r\n    \/\/ Thread'leri ba\u015flatal\u0131m\r\n    auto result1 = std::async(std::launch::async, fun1);\r\n    auto result2 = std::async(std::launch::async, fun2);\r\n \r\n    \/\/ Threadlerden haber bekleyelim\r\n    fut1.wait();\r\n    fut2.wait();\r\n \r\n    \/\/ Threadler haz\u0131rm\u0131\u015f\r\n    start = std::chrono::high_resolution_clock::now();\r\n \r\n    \/\/ \u015eimdi bekleyen thread'leri haberdar edelim \r\n    ready_promise.set_value();\r\n \r\n    std::cout &lt;&lt; \"Thread 1 received the signal \"\r\n              &lt;&lt; result1.get().count() &lt;&lt; \" ms after start\\n\"\r\n              &lt;&lt; \"Thread 2 received the signal \"\r\n              &lt;&lt; result2.get().count() &lt;&lt; \" ms after start\\n\";\r\n\r\n    return 0;\r\n}<\/pre>\n<h2><span style=\"color: #0000ff;\">std::<\/span><span style=\"color: #0000ff;\">packaged_task:<\/span><\/h2>\n<p>std::future, promise ve async ile ilintili bir di\u011fer s\u0131n\u0131f da\u00a0std::packaged_task&lt;&gt; s\u0131n\u0131f\u0131. Bu s\u0131n\u0131f, asenkron olarak \u00e7a\u011fr\u0131labilecek olan i\u015flevleri temsil eder, async() metodu ise direk ba\u015flat\u0131yordu hat\u0131rlarsan\u0131z (birazdan sekme sekme farklar\u0131 da ifade edece\u011fim). \u0130lgili i\u015flevlerin d\u00f6n\u00fc\u015f de\u011ferleri veya hata durumlar\u0131 yine ayn\u0131 nesne i\u00e7erisinde tutulur ve <span style=\"color: #008000;\"><strong><span class=\"t-lc\"><a style=\"color: #008000;\" title=\"cpp\/thread\/future\" href=\"https:\/\/en.cppreference.com\/w\/cpp\/thread\/future\">std::future<\/a><\/span><\/strong><\/span>\u00a0nesneleri \u00fczerinden eri\u015filir. Bu s\u0131n\u0131f a\u015fa\u011f\u0131dakileri kapsar:<\/p>\n<ul>\n<li>\u00c7a\u011fr\u0131labilir birimleri ki bunlar ba\u011f\u0131ms\u0131z bir fonksiyon, fonksiyon i\u015faret\u00e7isi, lambda fonksiyonu ya da fonksiyon nesnesi,<\/li>\n<li>\u0130lgili \u00e7a\u011fr\u0131labilir birimlere ait d\u00f6n\u00fc\u015f de\u011feri veya hata durumlar\u0131n\u0131n sakland\u0131\u011f\u0131 veri.<\/li>\n<\/ul>\n<p>Burada ilgili std::packaged_task nesnesinden elde edece\u011finiz std::future nesnesi ile ilgili i\u015flevden d\u00f6n\u00fclen de\u011fere ve hata durumuna bakabilirsiniz. A\u015fa\u011f\u0131da bu s\u0131n\u0131f\u0131n kullan\u0131m\u0131na ili\u015fkin \u00f6rnek bir kod bulabilirsiniz:<\/p>\n<pre class=\"lang:c++ decode:true \">#include &lt;iostream&gt;\r\n#include &lt;cmath&gt;\r\n#include &lt;thread&gt;\r\n#include &lt;future&gt;\r\n#include &lt;functional&gt;\r\n \r\n\/\/ Say\u0131n\u0131n \u00fcss\u00fcn\u00fc hesaplama i\u00e7in \u00f6rnek fonksiyon\r\nint f(int x, int y) \r\n{ \r\n   return std::pow(x, y); \r\n}\r\n \r\nvoid taskLambda()\r\n{\r\n    \/\/ packaged_task nesnesi lambda fonksiyonu ile\r\n    std::packaged_task&lt;int(int,int)&gt; task([](int a, int b) \r\n    {\r\n        return std::pow(a, b); \r\n    });\r\n\r\n    \/\/ Sonu\u00e7 kontrol etmek i\u00e7in future nesnesini edinelim\r\n    std::future&lt;int&gt; result = task.get_future();\r\n \r\n    \/\/ \u0130\u015flevi ba\u015flatal\u0131m\r\n    task(2, 9);\r\n \r\n    \/\/ Sonu\u00e7 i\u00e7in bekleyelim\r\n    std::cout &lt;&lt; \"taskLambda:\\t\" &lt;&lt; result.get() &lt;&lt; '\\n';\r\n}\r\n \r\nvoid taskBind()\r\n{\r\n    \/\/ packaged_task metot ba\u011flama kullan\u0131m\u0131\r\n    std::packaged_task&lt;int()&gt; task(std::bind(f, 2, 11));\r\n    std::future&lt;int&gt; result = task.get_future();\r\n \r\n    \/\/ \u0130\u015flevi ba\u015flatal\u0131m\r\n    task();\r\n \r\n    std::cout &lt;&lt; \"taskBind:\\t\" &lt;&lt; result.get() &lt;&lt; '\\n';\r\n}\r\n \r\nvoid taskThread()\r\n{\r\n    \/\/ packaged_task standart fonksiyon ile kullan\u0131m\u0131\r\n    std::packaged_task&lt;int(int,int)&gt; task(f);\r\n    std::future&lt;int&gt; result = task.get_future();\r\n \r\n    \/\/ \u0130lgili threade std::packaged_task nesnesini ge\u00e7irelim ve i\u015flevi ba\u015flatal\u0131m\r\n    std::thread task_td(std::move(task), 2, 10);\r\n\r\n    \/\/ Threadin tamamlanmas\u0131n\u0131 bekleyelim\r\n    task_td.join();\r\n \r\n    std::cout &lt;&lt; \"taskThread:\\t\" &lt;&lt; result.get() &lt;&lt; '\\n';\r\n}\r\n \r\nint main()\r\n{\r\n    taskLambda();\r\n    taskBind();\r\n    taskThread();\r\n\r\n    return 0;\r\n}<\/pre>\n<p>Yukar\u0131daki \u00f6rnekten de g\u00f6rece\u011finiz \u00fczere std::packaged_task nesnelerini kopyalayamazs\u0131n\u0131z, sadece ta\u015f\u0131yabilirsiniz. Bu sebeple, ilgili nesne, threadlere ge\u00e7irilmeden \u00f6nce genelde, std::future nesnesi tutulur (thread e ilgili std::packaged_task nesnesi ta\u015f\u0131naca\u011f\u0131 i\u00e7in elimizde bir kopya kalmaz).<\/p>\n<p>Gelelim sadede, packaged_task ile async metodu aras\u0131ndaki fark ne peki? G\u00fczel bir soru? Bu farklar\u0131 k\u0131saca a\u015fa\u011f\u0131daki gibi \u00f6zetleyebiliriz:<\/p>\n<ul>\n<li>\u0130lk olarak, async \u00e7a\u011fr\u0131s\u0131 ile ilgili i\u015flev hemen ba\u015flat\u0131l\u0131r, fakat std::packaged_task durumunda kontrol sizdedir. Ne zaman ba\u015flat API&#8217;sini \u00e7a\u011f\u0131r\u0131rsan\u0131z o zaman ba\u015flar,<\/li>\n<li>std::packaged_task nesnesinde elde edece\u011finiz std::future nesnesine ait get() API&#8217;sini \u00e7a\u011f\u0131rmadan, ilgili\u00a0std::packaged_task i\u015flevini ba\u015flatm\u0131\u015f olmal\u0131s\u0131n\u0131z. Yoksa uygulaman\u0131z sonsuza kadar tak\u0131l\u0131 kal\u0131r,<\/li>\n<li>async metodunda ilgili i\u015flevin hangi thread&#8217;te \u00e7a\u011fr\u0131laca\u011f\u0131n\u0131 belirleyemezsiniz. Fakat,\u00a0std::packaged_task nesneleri farkl\u0131 thread&#8217;lere aktar\u0131larak orada \u00e7al\u0131\u015ft\u0131r\u0131labilir,<\/li>\n<li>Asl\u0131nda async() arka tarafta std::packaged_task mekanizmas\u0131n\u0131 kullan\u0131yor gibi d\u00fc\u015f\u00fcnebilirsiniz. std::packaged_task biraz daha alt seviye bir \u00f6zellik ve async&#8217;in yapt\u0131\u011f\u0131 i\u015f std::thread ve std::packaged_task kullan\u0131larak ger\u00e7ekle\u015ftirilebilir.<\/li>\n<\/ul>\n<p>Evet sstd::packaged_task konusu da bu kadar.<\/p>\n<h2><span style=\"color: #0000ff;\">Atomics:<\/span><\/h2>\n<p lang=\"ro-RO\">Bir \u00f6nceki yaz\u0131m\u0131 okuduysan\u0131z, multithreaded programlama da dikkat etmeniz gereken en \u00f6nemli konulardan birisi de thread&#8217;ler aras\u0131 payla\u015f\u0131lan verilerin korunmas\u0131d\u0131r. Bu anlamda thread k\u00fct\u00fcphanesinde, bir sonraki thread yaz\u0131mda da anlataca\u011f\u0131m \u00fczere, bir \u00e7ok yap\u0131 bulunmakta. Bu yaz\u0131mda ise thread k\u00fct\u00fcphanesi ile gelen ve basit veriler i\u00e7in bu tarz yap\u0131lardan bizi kurtaran bir yap\u0131dan bahsedece\u011fim. Bunlar: <em>Atomik Tiplerdir<\/em>. \u0130lgili referans (<strong><span style=\"color: #008000;\"><a style=\"color: #008000;\" href=\"https:\/\/en.cppreference.com\/w\/cpp\/atomic\/atomic\">std::atomic library referans sayfas\u0131<\/a>)<\/span><\/strong> sayfas\u0131nda da ifade edildi\u011fi \u00fczere bu yap\u0131lar, i\u00e7erisinde bar\u0131nd\u0131rd\u0131\u011f\u0131 veri tiplerine, bir \u00e7ok thread&#8217;in eri\u015fimine herhangi bir &#8220;data race&#8221; ya da problem olmadan, senkronize bir \u015fekilde eri\u015fimini sa\u011flarlar. Daha fazla detaya girmeden \u00f6nce hemen \u00f6rnek bir kod \u00fczerinden ge\u00e7elim:<\/p>\n<pre class=\"lang:c++ decode:true code literal-block \">class ShredCounter \r\n{\r\npublic:\r\n    void increment()\r\n    {\r\n        ++mValue;\r\n    }\r\n\u00a0 \u00a0\u00a0\r\n    void decrement()\r\n    {\r\n        --mValue;\r\n    }\r\n\u00a0 \u00a0\u00a0\r\n    int get() \r\n    {\r\n        return mValue\r\n    }\r\n\r\n    void set(int newValue)\r\n    {\r\n        mValue = newValue;\r\n    }\r\nprivate:   \r\n   \/\/ Payla\u015f\u0131lacak olan veri\r\n   int mValue;\r\n};<\/pre>\n<p>Yukar\u0131daki \u00f6rnek kodun \u00fczerinden ge\u00e7er ge\u00e7mez, bu s\u0131n\u0131f\u0131n multithreaded ortamlar i\u00e7in uygun ve g\u00fcvenli olmad\u0131\u011f\u0131n\u0131 anlam\u0131\u015fs\u0131n\u0131zd\u0131r. Normal \u015fartlarda std::mutex ve benzeri yap\u0131lar\u0131 kullanarak bunu g\u00fcvenli hale getirebiliriz. \u015eimdi, bu kodu atomik tipleri kullanarak nas\u0131l g\u00fcvenli hale getirebilece\u011fimize bakal\u0131m.<\/p>\n<p>\u00d6ncelikli olarak atomik tipler de, yukar\u0131da bahsetti\u011fim s\u0131n\u0131flar gibi \u015fablon bir s\u0131n\u0131f (template class). Kullanabilmek i\u00e7in\u00a0<code>&lt;atomic&gt;<\/code>\u00a0ba\u015fl\u0131k dosyas\u0131n\u0131 eklemeniz gerekiyor. Bu s\u0131n\u0131f\u0131n \u015fablon parametresi olarak da payla\u015fmak istedi\u011finiz veri tipini giriyorsunuz (k\u00fct\u00fcphane i\u00e7erisinde bilindik veri tipleri i\u00e7in haz\u0131r tipler mevcut. Bu yap\u0131n\u0131n alt tarafta kulland\u0131\u011f\u0131 senkronizasyon mekanizmas\u0131, ilgili k\u00fct\u00fcphane ger\u00e7eklemesine ve parametre olarak ge\u00e7irilen tipe ba\u011fl\u0131. Basit veri tipleri i\u00e7in, \u00f6r. int, long, float, bool, vb., std::mutex ve benzeri yap\u0131lardan \u00e7ok daha performansl\u0131 ve &#8220;lock-free&#8221; \u015fekilde eri\u015fim sa\u011flanabilir (tabi burada &#8220;lock-free&#8221; olmas\u0131 i\u015flemci taraf\u0131ndan sunulan i\u015flemci komutlar\u0131na ba\u011fl\u0131).\u00a0 E\u011fer daha karma\u015f\u0131k tipler kullan\u0131r iseniz de, sistem, arka tarafta std::mutex&#8217;leri kullanarak gerekli senkronizasyon i\u015flevini yerine getiriyor. Bu arada &#8220;lock-free&#8221; deste\u011fi ayr\u0131ca sunulan\u00a0<em>is_lock_free()<\/em> API&#8217;is ile de kontrol edilebilir. <strong><span style=\"color: #008000;\">https:\/\/en.cppreference.com\/w\/cpp\/atomic\/atomic\/is_lock_free<\/span><\/strong>\u00a0sayfas\u0131ndan ald\u0131\u011f\u0131m a\u015fa\u011f\u0131daki \u00f6rnek kod ile devam edelim:<\/p>\n<pre class=\"lang:c++ decode:true \">#include &lt;iostream&gt;\r\n#include &lt;utility&gt;\r\n#include &lt;atomic&gt;\r\n\u00a0\r\nstruct A \r\n{ \r\n  int a[100]; \r\n};\r\nstruct B \r\n{ \r\n  int x;\r\n  int y; \r\n};\r\nint main()\r\n{\r\n    std::cout &lt;&lt; std::boolalpha\r\n              &lt;&lt; \"std::atomic&lt;A&gt; is lock free? \"\r\n              &lt;&lt; std::atomic&lt;A&gt;{}.is_lock_free() &lt;&lt; '\\n'\r\n              &lt;&lt; \"std::atomic&lt;B&gt; is lock free? \"\r\n              &lt;&lt; std::atomic&lt;B&gt;{}.is_lock_free() &lt;&lt; '\\n';\r\n}<\/pre>\n<p>Bu s\u0131n\u0131f taraf\u0131ndan sunulan API&#8217;ler\u00a0<em>store<\/em>() ve\u00a0<em>load<\/em>() metotlar\u0131d\u0131r. Bunlar ilgili verilere eri\u015fim ve g\u00fcncelleme i\u00e7in kullanabilirler. Ayn\u0131 zaman atama operat\u00f6r\u00fc de kullan\u0131labilir. Bir di\u011fer kullan\u0131\u015fl\u0131 API ise <em>exchange()&#8217;dir<\/em>, bu API verilen parametreyi ilgili atomik de\u011fi\u015fkene atar ve \u00f6nceki de\u011feri d\u00f6ner. Son olarak kullanabilece\u011finiz iki API daha var. Bunlar <em>compare_exchange_weak()<\/em>\u00a0ve\u00a0<em>compare_exchance_strong(). <\/em>Bunlar ise de\u011fi\u015fkene veri atama i\u015fini sadece verilen de\u011fer mevcut de\u011fere e\u015fit ise yapar. Son \u00fc\u00e7 API, genelde &#8220;lock-free&#8221; algoritmalar ve veri yap\u0131lar\u0131nda s\u0131kl\u0131k ile kullan\u0131l\u0131r (umar\u0131m bu konu ile ilgili de bir yaz\u0131 sizler ile payla\u015faca\u011f\u0131m). Ayr\u0131ca b\u00fct\u00fcn tam say\u0131 tipleri i\u00e7in ++, &#8211;, fetch_add, fetch_sub operat\u00f6r ve API&#8217;leri de tan\u0131ml\u0131d\u0131r (tam liste i\u00e7in <span style=\"color: #008000;\"><strong><a style=\"color: #008000;\" href=\"https:\/\/en.cppreference.com\/w\/cpp\/atomic\/atomic\">https:\/\/en.cppreference.com\/w\/cpp\/atomic\/atomic&#8217;<\/a><\/strong><\/span>e ba\u015fvurabilirsiniz).<\/p>\n<p>\u015eimdi, yukar\u0131daki s\u0131n\u0131f\u0131m\u0131z std::atomic&#8217;i kullanarak g\u00fcvenli hale getirelim:<\/p>\n<pre class=\"lang:c++ decode:true code literal-block\">#include &lt;atomic&gt;\r\n\r\nclass ShredCounter \r\n{\r\npublic:\r\n    void increment()\r\n    {\r\n        ++mValue;\r\n    }\r\n\u00a0 \u00a0\u00a0\r\n    void decrement()\r\n    {\r\n        --mValue;\r\n    }\r\n\u00a0 \u00a0\u00a0\r\n    int get() \r\n    {\r\n        return mValue.load();\r\n    }\r\n\r\n    void set(int newValue)\r\n    {\r\n        mValue.store(newValue);\r\n    }\r\nprivate:   \r\n   \/\/ Thread'ler taraf\u0131ndan payla\u015f\u0131lacak de\u011fi\u015fken\r\n   std::atomic&lt;int&gt; mValue;\r\n};<\/pre>\n<p lang=\"ro-RO\">Kanaatimce, atomiklerin en b\u00fcy\u00fck avantaj\u0131, basit tipler i\u00e7in performans ve okunabilirlik. Bu sebeple, \u00f6zellikle basit veri tipleri i\u00e7in olabildi\u011fince std::atomics&#8217;leri kullanman\u0131z\u0131 tavsiye ediyorum.<\/p>\n<p lang=\"ro-RO\">C++ 20 ile birlikte bu tiplere baz\u0131 eklemeler de yap\u0131ld\u0131. Art\u0131k std::shared_ptr ve weak_ptr&#8217;da atomik olarak kullan\u0131labilecek. Detayl\u0131 bilgi i\u00e7in \u015fu sayfaya g\u00f6z atabilirsiniz:\u00a0<strong><span style=\"color: #008000;\"><a style=\"color: #008000;\" href=\"https:\/\/en.cppreference.com\/w\/cpp\/atomic\/atomic\">https:\/\/en.cppreference.com\/w\/cpp\/atomic\/atomic<\/a><\/span><\/strong>.<\/p>\n<p lang=\"ro-RO\">Bu arada, atomik&#8217;ler ile ilgili bir di\u011fer konu da bellek s\u0131ralamas\u0131 (<span style=\"color: #008000;\"><strong><a style=\"color: #008000;\" href=\"https:\/\/en.cppreference.com\/w\/cpp\/atomic\/memory_order\">https:\/\/en.cppreference.com\/w\/cpp\/atomic\/memory_order<\/a><\/strong><\/span>) ki ben bu konuya girmedim. \u0130lgili referans dok\u00fcmanda da \u00f6zetlendi\u011fi gibi, bu mekanizma, atomik ve \u00f6nceki\/sonraki i\u015flemci komutlar\u0131n\u0131n nas\u0131l s\u0131raland\u0131\u011f\u0131n\u0131 tan\u0131ml\u0131yor. Bu konu ile ilgili daha detayl\u0131 bilgi almak i\u00e7in bahsetti\u011fim sayfaya g\u00f6z atabilirsiniz.<\/p>\n<p lang=\"ro-RO\">Bir sonraki yaz\u0131mda g\u00f6r\u00fc\u015fmek dile\u011fiyle \ud83d\ude42<\/p>\n<h2 lang=\"ro-RO\"><span style=\"color: #0000ff;\"><strong>Referanslar:<\/strong><\/span><\/h2>\n<ul>\n<li lang=\"ro-RO\"><a href=\"https:\/\/thispointer.com\/c11-multithreading-part-9-stdasync-tutorial-example\/\"><span style=\"color: #008000;\"><strong>https:\/\/thispointer.com\/c11-multithreading-part-9-stdasync-tutorial-example\/<\/strong><\/span><\/a><\/li>\n<li lang=\"ro-RO\"><a href=\"https:\/\/en.cppreference.com\/w\/cpp\/atomic\"><span style=\"color: #008000;\"><strong>https:\/\/en.cppreference.com\/w\/cpp\/atomic<\/strong><\/span><\/a><\/li>\n<li lang=\"ro-RO\"><a href=\"https:\/\/www.developerfusion.com\/article\/138018\/memory-ordering-for-atomic-operations-in-c0x\/\"><span style=\"color: #008000;\"><strong>https:\/\/www.developerfusion.com\/article\/138018\/memory-ordering-for-atomic-operations-in-c0x\/<\/strong><\/span><\/a><\/li>\n<li lang=\"ro-RO\"><a href=\"https:\/\/bartoszmilewski.com\/2008\/12\/01\/c-atomics-and-memory-ordering\/\"><span style=\"color: #008000;\"><strong>https:\/\/bartoszmilewski.com\/2008\/12\/01\/c-atomics-and-memory-ordering\/<\/strong><\/span><\/a><\/li>\n<li lang=\"ro-RO\"><a href=\"http:\/\/scottmeyers.blogspot.com\/2013\/03\/stdfutures-from-stdasync-arent-special.html\"><span style=\"color: #008000;\"><strong>http:\/\/scottmeyers.blogspot.com\/2013\/03\/stdfutures-from-stdasync-arent-special.html<\/strong><\/span><\/a><\/li>\n<li lang=\"ro-RO\"><a href=\"http:\/\/www.modernescpp.com\/index.php\/promise-and-future\"><span style=\"color: #008000;\"><strong>http:\/\/www.modernescpp.com\/index.php\/promise-and-future<\/strong><\/span><\/a><\/li>\n<li lang=\"ro-RO\"><a href=\"https:\/\/en.cppreference.com\/w\/cpp\/atomic\/atomic\"><span style=\"color: #008000;\"><strong>https:\/\/en.cppreference.com\/w\/cpp\/atomic\/atomic<\/strong><\/span><\/a><\/li>\n<li lang=\"ro-RO\"><a href=\"https:\/\/en.cppreference.com\/w\/cpp\/atomic\/memory_order\"><span style=\"color: #008000;\"><strong>https:\/\/en.cppreference.com\/w\/cpp\/atomic\/memory_order<\/strong><\/span><\/a><\/li>\n<\/ul>\n<p><\/p>","protected":false},"excerpt":{"rendered":"<p>Evet, thread ile ilgili yaz\u0131lar\u0131m\u0131za devam etme zaman\u0131 geldi. Bu yaz\u0131mda, sizlere thread k\u00fct\u00fcphanesi i\u00e7erisinde bulunan ve C++ kullanarak multithreaded yaz\u0131l\u0131m geli\u015ftirme esnas\u0131nda, size faydas\u0131 dokunaca\u011f\u0131n\u0131 d\u00fc\u015f\u00fcnd\u00fc\u011f\u00fcm yap\u0131lardan bahsedece\u011fim. Thread k\u00fct\u00fcphanesi ve ilgili girizgah\u0131 bir \u00f6nceki yaz\u0131mda yapm\u0131\u015ft\u0131m, e\u011fer onu okumad\u0131ysan\u0131z, mutlaka okuman\u0131z\u0131 \u00f6neririm. A\u015fa\u011f\u0131da ilgili yaz\u0131ma ve serinin di\u011fer yaz\u0131lar\u0131na ili\u015fkin ba\u011flant\u0131lar\u0131 bulabilirsiniz: Haftal\u0131k&#8230; <a class=\"more-link\" href=\"https:\/\/www.yazilimperver.com\/index.php\/2019\/01\/28\/english-weekly-c-8-stdthread-ii\/\">Continue reading <span class=\"meta-nav\">&#8594;<\/span><\/a><\/p>\n","protected":false},"author":2,"featured_media":174,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_monsterinsights_skip_tracking":false,"_monsterinsights_sitenote_active":false,"_monsterinsights_sitenote_note":"","_monsterinsights_sitenote_category":0,"footnotes":""},"categories":[10,41],"tags":[322,320,316,323,321,317,324,328,327,325,42,292,319,318,326],"class_list":["post-862","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-c","category-modern-c","tag-async","tag-atomics","tag-c-11-thread-library-async","tag-deferred","tag-features","tag-future","tag-launch","tag-lock-free-data-structure","tag-lock-free","tag-memory_order","tag-modern-c","tag-multithreaded-programming","tag-packaged_task","tag-promise","tag-shared_future"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v21.0 - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>Haftal\u0131k C++ 8- std::thread (II) - Yaz\u0131l\u0131mperver&#039;in D\u00fcnyas\u0131<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.yazilimperver.com\/index.php\/2019\/01\/28\/english-weekly-c-8-stdthread-ii\/\" \/>\n<meta property=\"og:locale\" content=\"tr_TR\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"[:tr]Haftal\u0131k C++ 8- std::thread (II)[:en]Weekly C++ 8- std::thread (II)[:] - Yaz\u0131l\u0131mperver&#039;in D\u00fcnyas\u0131\" \/>\n<meta property=\"og:description\" content=\"Evet, thread ile ilgili yaz\u0131lar\u0131m\u0131za devam etme zaman\u0131 geldi. Bu yaz\u0131mda, sizlere thread k\u00fct\u00fcphanesi i\u00e7erisinde bulunan ve C++ kullanarak multithreaded yaz\u0131l\u0131m geli\u015ftirme esnas\u0131nda, size faydas\u0131 dokunaca\u011f\u0131n\u0131 d\u00fc\u015f\u00fcnd\u00fc\u011f\u00fcm yap\u0131lardan bahsedece\u011fim. Thread k\u00fct\u00fcphanesi ve ilgili girizgah\u0131 bir \u00f6nceki yaz\u0131mda yapm\u0131\u015ft\u0131m, e\u011fer onu okumad\u0131ysan\u0131z, mutlaka okuman\u0131z\u0131 \u00f6neririm. A\u015fa\u011f\u0131da ilgili yaz\u0131ma ve serinin di\u011fer yaz\u0131lar\u0131na ili\u015fkin ba\u011flant\u0131lar\u0131 bulabilirsiniz: Haftal\u0131k... Continue reading &#8594;\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.yazilimperver.com\/index.php\/2019\/01\/28\/english-weekly-c-8-stdthread-ii\/\" \/>\n<meta property=\"og:site_name\" content=\"Yaz\u0131l\u0131mperver&#039;in D\u00fcnyas\u0131\" \/>\n<meta property=\"article:published_time\" content=\"2019-01-28T19:02:16+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2019-03-08T19:45:26+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.yazilimperver.com\/wp-content\/uploads\/2017\/12\/FeaturedImage-e1580417052514.png\" \/>\n\t<meta property=\"og:image:width\" content=\"32\" \/>\n\t<meta property=\"og:image:height\" content=\"32\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/png\" \/>\n<meta name=\"author\" content=\"yaz\u0131l\u0131mperver\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Yazan:\" \/>\n\t<meta name=\"twitter:data1\" content=\"yaz\u0131l\u0131mperver\" \/>\n\t<meta name=\"twitter:label2\" content=\"Tahmini okuma s\u00fcresi\" \/>\n\t<meta name=\"twitter:data2\" content=\"37 dakika\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/www.yazilimperver.com\/index.php\/2019\/01\/28\/english-weekly-c-8-stdthread-ii\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/www.yazilimperver.com\/index.php\/2019\/01\/28\/english-weekly-c-8-stdthread-ii\/\"},\"author\":{\"name\":\"yaz\u0131l\u0131mperver\",\"@id\":\"https:\/\/www.yazilimperver.com\/#\/schema\/person\/6497f6de4df6ba469748b861a2b3fcdb\"},\"headline\":\"Haftal\u0131k C++ 8- std::thread (II)\",\"datePublished\":\"2019-01-28T19:02:16+00:00\",\"dateModified\":\"2019-03-08T19:45:26+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/www.yazilimperver.com\/index.php\/2019\/01\/28\/english-weekly-c-8-stdthread-ii\/\"},\"wordCount\":4780,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\/\/www.yazilimperver.com\/#\/schema\/person\/6497f6de4df6ba469748b861a2b3fcdb\"},\"keywords\":[\"async\",\"atomics\",\"C++ 11 thread library async\",\"deferred\",\"features\",\"future\",\"launch\",\"lock free data structure\",\"lock-free\",\"memory_order\",\"Modern C++\",\"multithreaded programming\",\"packaged_task\",\"promise\",\"shared_future\"],\"articleSection\":[\"C++\",\"Modern C++\"],\"inLanguage\":\"tr\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\/\/www.yazilimperver.com\/index.php\/2019\/01\/28\/english-weekly-c-8-stdthread-ii\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/www.yazilimperver.com\/index.php\/2019\/01\/28\/english-weekly-c-8-stdthread-ii\/\",\"url\":\"https:\/\/www.yazilimperver.com\/index.php\/2019\/01\/28\/english-weekly-c-8-stdthread-ii\/\",\"name\":\"[:tr]Haftal\u0131k C++ 8- std::thread (II)[:en]Weekly C++ 8- std::thread (II)[:] - Yaz\u0131l\u0131mperver&#039;in D\u00fcnyas\u0131\",\"isPartOf\":{\"@id\":\"https:\/\/www.yazilimperver.com\/#website\"},\"datePublished\":\"2019-01-28T19:02:16+00:00\",\"dateModified\":\"2019-03-08T19:45:26+00:00\",\"breadcrumb\":{\"@id\":\"https:\/\/www.yazilimperver.com\/index.php\/2019\/01\/28\/english-weekly-c-8-stdthread-ii\/#breadcrumb\"},\"inLanguage\":\"tr\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/www.yazilimperver.com\/index.php\/2019\/01\/28\/english-weekly-c-8-stdthread-ii\/\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/www.yazilimperver.com\/index.php\/2019\/01\/28\/english-weekly-c-8-stdthread-ii\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Ana sayfa\",\"item\":\"https:\/\/www.yazilimperver.com\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Haftal\u0131k C++ 8- std::thread (II)\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/www.yazilimperver.com\/#website\",\"url\":\"https:\/\/www.yazilimperver.com\/\",\"name\":\"Yaz\u0131l\u0131mperver&#039;in D\u00fcnyas\u0131\",\"description\":\"Payla\u015fmak g\u00fczeldir.\",\"publisher\":{\"@id\":\"https:\/\/www.yazilimperver.com\/#\/schema\/person\/6497f6de4df6ba469748b861a2b3fcdb\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/www.yazilimperver.com\/?s={search_term_string}\"},\"query-input\":\"required name=search_term_string\"}],\"inLanguage\":\"tr\"},{\"@type\":[\"Person\",\"Organization\"],\"@id\":\"https:\/\/www.yazilimperver.com\/#\/schema\/person\/6497f6de4df6ba469748b861a2b3fcdb\",\"name\":\"yaz\u0131l\u0131mperver\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"tr\",\"@id\":\"https:\/\/www.yazilimperver.com\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/www.yazilimperver.com\/wp-content\/uploads\/2018\/04\/OnlyIcon-1-114x114.png\",\"contentUrl\":\"https:\/\/www.yazilimperver.com\/wp-content\/uploads\/2018\/04\/OnlyIcon-1-114x114.png\",\"caption\":\"yaz\u0131l\u0131mperver\"},\"logo\":{\"@id\":\"https:\/\/www.yazilimperver.com\/#\/schema\/person\/image\/\"}}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"[:tr]Haftal\u0131k C++ 8- std::thread (II)[:en]Weekly C++ 8- std::thread (II)[:] - Yaz\u0131l\u0131mperver&#039;in D\u00fcnyas\u0131","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.yazilimperver.com\/index.php\/2019\/01\/28\/english-weekly-c-8-stdthread-ii\/","og_locale":"tr_TR","og_type":"article","og_title":"[:tr]Haftal\u0131k C++ 8- std::thread (II)[:en]Weekly C++ 8- std::thread (II)[:] - Yaz\u0131l\u0131mperver&#039;in D\u00fcnyas\u0131","og_description":"Evet, thread ile ilgili yaz\u0131lar\u0131m\u0131za devam etme zaman\u0131 geldi. Bu yaz\u0131mda, sizlere thread k\u00fct\u00fcphanesi i\u00e7erisinde bulunan ve C++ kullanarak multithreaded yaz\u0131l\u0131m geli\u015ftirme esnas\u0131nda, size faydas\u0131 dokunaca\u011f\u0131n\u0131 d\u00fc\u015f\u00fcnd\u00fc\u011f\u00fcm yap\u0131lardan bahsedece\u011fim. Thread k\u00fct\u00fcphanesi ve ilgili girizgah\u0131 bir \u00f6nceki yaz\u0131mda yapm\u0131\u015ft\u0131m, e\u011fer onu okumad\u0131ysan\u0131z, mutlaka okuman\u0131z\u0131 \u00f6neririm. A\u015fa\u011f\u0131da ilgili yaz\u0131ma ve serinin di\u011fer yaz\u0131lar\u0131na ili\u015fkin ba\u011flant\u0131lar\u0131 bulabilirsiniz: Haftal\u0131k... Continue reading &#8594;","og_url":"https:\/\/www.yazilimperver.com\/index.php\/2019\/01\/28\/english-weekly-c-8-stdthread-ii\/","og_site_name":"Yaz\u0131l\u0131mperver&#039;in D\u00fcnyas\u0131","article_published_time":"2019-01-28T19:02:16+00:00","article_modified_time":"2019-03-08T19:45:26+00:00","og_image":[{"width":32,"height":32,"url":"https:\/\/www.yazilimperver.com\/wp-content\/uploads\/2017\/12\/FeaturedImage-e1580417052514.png","type":"image\/png"}],"author":"yaz\u0131l\u0131mperver","twitter_card":"summary_large_image","twitter_misc":{"Yazan:":"yaz\u0131l\u0131mperver","Tahmini okuma s\u00fcresi":"37 dakika"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.yazilimperver.com\/index.php\/2019\/01\/28\/english-weekly-c-8-stdthread-ii\/#article","isPartOf":{"@id":"https:\/\/www.yazilimperver.com\/index.php\/2019\/01\/28\/english-weekly-c-8-stdthread-ii\/"},"author":{"name":"yaz\u0131l\u0131mperver","@id":"https:\/\/www.yazilimperver.com\/#\/schema\/person\/6497f6de4df6ba469748b861a2b3fcdb"},"headline":"Haftal\u0131k C++ 8- std::thread (II)","datePublished":"2019-01-28T19:02:16+00:00","dateModified":"2019-03-08T19:45:26+00:00","mainEntityOfPage":{"@id":"https:\/\/www.yazilimperver.com\/index.php\/2019\/01\/28\/english-weekly-c-8-stdthread-ii\/"},"wordCount":4780,"commentCount":0,"publisher":{"@id":"https:\/\/www.yazilimperver.com\/#\/schema\/person\/6497f6de4df6ba469748b861a2b3fcdb"},"keywords":["async","atomics","C++ 11 thread library async","deferred","features","future","launch","lock free data structure","lock-free","memory_order","Modern C++","multithreaded programming","packaged_task","promise","shared_future"],"articleSection":["C++","Modern C++"],"inLanguage":"tr","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/www.yazilimperver.com\/index.php\/2019\/01\/28\/english-weekly-c-8-stdthread-ii\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/www.yazilimperver.com\/index.php\/2019\/01\/28\/english-weekly-c-8-stdthread-ii\/","url":"https:\/\/www.yazilimperver.com\/index.php\/2019\/01\/28\/english-weekly-c-8-stdthread-ii\/","name":"[:tr]Haftal\u0131k C++ 8- std::thread (II)[:en]Weekly C++ 8- std::thread (II)[:] - Yaz\u0131l\u0131mperver&#039;in D\u00fcnyas\u0131","isPartOf":{"@id":"https:\/\/www.yazilimperver.com\/#website"},"datePublished":"2019-01-28T19:02:16+00:00","dateModified":"2019-03-08T19:45:26+00:00","breadcrumb":{"@id":"https:\/\/www.yazilimperver.com\/index.php\/2019\/01\/28\/english-weekly-c-8-stdthread-ii\/#breadcrumb"},"inLanguage":"tr","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.yazilimperver.com\/index.php\/2019\/01\/28\/english-weekly-c-8-stdthread-ii\/"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/www.yazilimperver.com\/index.php\/2019\/01\/28\/english-weekly-c-8-stdthread-ii\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Ana sayfa","item":"https:\/\/www.yazilimperver.com\/"},{"@type":"ListItem","position":2,"name":"Haftal\u0131k C++ 8- std::thread (II)"}]},{"@type":"WebSite","@id":"https:\/\/www.yazilimperver.com\/#website","url":"https:\/\/www.yazilimperver.com\/","name":"Yaz\u0131l\u0131mperver&#039;in D\u00fcnyas\u0131","description":"Payla\u015fmak g\u00fczeldir.","publisher":{"@id":"https:\/\/www.yazilimperver.com\/#\/schema\/person\/6497f6de4df6ba469748b861a2b3fcdb"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.yazilimperver.com\/?s={search_term_string}"},"query-input":"required name=search_term_string"}],"inLanguage":"tr"},{"@type":["Person","Organization"],"@id":"https:\/\/www.yazilimperver.com\/#\/schema\/person\/6497f6de4df6ba469748b861a2b3fcdb","name":"yaz\u0131l\u0131mperver","image":{"@type":"ImageObject","inLanguage":"tr","@id":"https:\/\/www.yazilimperver.com\/#\/schema\/person\/image\/","url":"https:\/\/www.yazilimperver.com\/wp-content\/uploads\/2018\/04\/OnlyIcon-1-114x114.png","contentUrl":"https:\/\/www.yazilimperver.com\/wp-content\/uploads\/2018\/04\/OnlyIcon-1-114x114.png","caption":"yaz\u0131l\u0131mperver"},"logo":{"@id":"https:\/\/www.yazilimperver.com\/#\/schema\/person\/image\/"}}]}},"_links":{"self":[{"href":"https:\/\/www.yazilimperver.com\/index.php\/wp-json\/wp\/v2\/posts\/862","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.yazilimperver.com\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.yazilimperver.com\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.yazilimperver.com\/index.php\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/www.yazilimperver.com\/index.php\/wp-json\/wp\/v2\/comments?post=862"}],"version-history":[{"count":32,"href":"https:\/\/www.yazilimperver.com\/index.php\/wp-json\/wp\/v2\/posts\/862\/revisions"}],"predecessor-version":[{"id":1039,"href":"https:\/\/www.yazilimperver.com\/index.php\/wp-json\/wp\/v2\/posts\/862\/revisions\/1039"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.yazilimperver.com\/index.php\/wp-json\/wp\/v2\/media\/174"}],"wp:attachment":[{"href":"https:\/\/www.yazilimperver.com\/index.php\/wp-json\/wp\/v2\/media?parent=862"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.yazilimperver.com\/index.php\/wp-json\/wp\/v2\/categories?post=862"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.yazilimperver.com\/index.php\/wp-json\/wp\/v2\/tags?post=862"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}