{"id":874,"date":"2019-03-08T19:43:09","date_gmt":"2019-03-08T19:43:09","guid":{"rendered":"http:\/\/www.yazilimperver.com\/?p=874"},"modified":"2019-03-23T20:57:43","modified_gmt":"2019-03-23T20:57:43","slug":"haftalik-c-10-stdthread-iii","status":"publish","type":"post","link":"https:\/\/www.yazilimperver.com\/index.php\/2019\/03\/08\/haftalik-c-10-stdthread-iii\/","title":{"rendered":"Haftal\u0131k C++ 10- std::thread (III)"},"content":{"rendered":"<p><span style=\"font-weight: 400;\">Merhaba arkada\u015flar, uzun bir aradan sonra haftal\u0131k C++ yaz\u0131lar\u0131m\u0131za devam ediyoruz. <em>std::thread<\/em> k\u00fct\u00fcphanesine ili\u015fkin daha \u00f6nce ba\u015flam\u0131\u015f oldu\u011fumuz serinin \u00fc\u00e7\u00fcnc\u00fc yaz\u0131s\u0131 ile sizler ile birlikteyim. E\u011fer di\u011fer yaz\u0131lar\u0131m\u0131 hen\u00fcz okumad\u0131 iseniz, a\u015fa\u011f\u0131daki ba\u011flant\u0131lardan muhakkak okuman\u0131z \u00f6neriyorum, \u00f6zellikle birinci yaz\u0131y\u0131:<\/span><\/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<h2><span style=\"font-weight: 400;\"><span style=\"color: #0000ff;\"><strong>Giri\u015f:<\/strong><\/span><\/span><\/h2>\n<p><span style=\"font-weight: 400;\">Gelelim bu yaz\u0131n\u0131n konusuna. Bundan \u00f6nceki yaz\u0131lar\u0131mda, temel <em>std::thread<\/em> kullan\u0131m\u0131 ve yard\u0131mc\u0131 yap\u0131lara de\u011finmi\u015ftim. Bu yaz\u0131mda ise, multithreaded yaz\u0131l\u0131m geli\u015ftirmede \u00e7ok \u00f6nemli bir yere sahip olan senkronizasyon yap\u0131lar\u0131ndan sizlere bahsedece\u011fim.\u00a0Asl\u0131nda bakarsan\u0131z, bir \u00f6nceki yaz\u0131mda anlatt\u0131\u011f\u0131m <em>std::atomics<\/em> de senkronizasyon yap\u0131lar\u0131ndan birisidir ve her ne kadar b\u00fct\u00fcn durumlar\u0131 kar\u015f\u0131lamasa da, burada anlataca\u011f\u0131m baz\u0131 problemler i\u00e7in kullan\u0131labilir.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">Senkronizasyon yap\u0131lar\u0131, \u00f6zellikle bir den fazla thread\u2019in ayn\u0131 bellek uzay\u0131ndaki ortak kaynaklara (\u00f6zellikle bellekte her iki thread\u2019in eri\u015fimi oldu\u011fu ve yerel olarak al\u0131nmam\u0131\u015f de\u011fi\u015fkenler) eri\u015ferek de\u011fi\u015ftirmek istedi\u011fi durumlarda, ortaya \u00e7\u0131kabilecek problemleri \u00f6nlemek i\u00e7in kullan\u0131l\u0131rlar. Bunun yan\u0131nda thread\u2019ler aras\u0131 haberle\u015fme ve koordinasyon i\u00e7in de kullan\u0131l\u0131rlar. Bunu uygulamak, tabi s\u00f6ylemekten biraz daha zor, \u00e7\u00fcnk\u00fc bu yap\u0131lar\u0131n yanl\u0131\u015f kullan\u0131lmas\u0131, bulunmas\u0131 ve ay\u0131klanmas\u0131 zor hatalara yol a\u00e7abilece\u011fi gibi, performans anlam\u0131nda da uygulamalar\u0131n\u0131za ket vurabilir. Bu sebeple de \u00f6zellikle kritik verilerin payla\u015f\u0131m\u0131 konusunu, olduk\u00e7a dikkatli de\u011ferlendirmenizde fayda var. Her ne kadar bu yaz\u0131mda de\u011finmesem de (ileride belki ayr\u0131 bir yaz\u0131da bu konuya de\u011finebiliriz), multithreaded programlama i\u00e7in kullan\u0131labilecek bir \u00e7ok tasar\u0131m kal\u0131plar\u0131 ve yakla\u015f\u0131mlar\u0131 mevcut, uygulamalar\u0131n\u0131zda m\u00fcmk\u00fcn oldu\u011funca bunlar\u0131 kullanman\u0131z, bu tarz problemler ile kar\u015f\u0131la\u015fma riskini azaltacakt\u0131r.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u015eimdi dilerseniz, bir \u00f6nceki paragrafta ortak kaynaklara eri\u015fim konusunu basit bir \u00f6rnekle inceleyelim:<\/span><\/p>\n<pre class=\"lang:c++ decode:true \">void saveItem(int item)\r\n{\r\n....\r\n    int freeSlotIndex{0};\r\n\r\n...\u00a0\u00a0\u00a0\u00a0\r\n\r\n    freeSlotIndex = foundFreeIndex;\r\n    storage[freeSlotIndex] = item;\r\n    foundFreeIndex++;\r\n\r\n....\r\n\r\n}<\/pre>\n<p><span style=\"font-weight: 400;\">Yukar\u0131daki metot basit\u00e7e verilen bir say\u0131y\u0131, basit bir dizide buldu\u011fu ilk yerde sakl\u0131yor. Normal \u015fartlarda, hi\u00e7bir s\u0131k\u0131nt\u0131 g\u00f6r\u00fcnmeyen bu metodun paralel \u00e7al\u0131\u015ft\u0131r\u0131lmas\u0131 durumunda kar\u015f\u0131la\u015fabilece\u011fimiz \u00f6rnek bir duruma g\u00f6z atal\u0131m. A\u015fa\u011f\u0131da iki farkl\u0131 thread\u2019in bu metodu ayn\u0131 anda \u00e7a\u011f\u0131rd\u0131\u011f\u0131 durumda, olu\u015fabilecek \u00f6rnek bir ko\u015fum s\u0131ras\u0131 vermeye \u00e7al\u0131\u015ft\u0131m (bu elbette de\u011fi\u015febilir).<\/span><\/p>\n<table>\n<tbody>\n<tr>\n<td><strong>Thread 1 Ko\u015fumu:<\/strong><\/td>\n<td><strong>Thread 2 Ko\u015fumu:<\/strong><\/td>\n<\/tr>\n<tr>\n<td><span style=\"font-weight: 400;\">1) freeSlotIndex = foundFreeIndex;<\/span><\/p>\n<p><span style=\"font-weight: 400; color: #ff0000;\">4) storage[freeSlotIndex] = item;<\/span><\/p>\n<p><span style=\"font-weight: 400;\">5) foundFreeIndex++;<\/span><\/td>\n<td><span style=\"font-weight: 400;\">2) freeSlotIndex = foundFreeIndex;<\/span><\/p>\n<p><span style=\"font-weight: 400;\"><span style=\"color: #ff0000;\">3) storage[freeSlotIndex] = item<\/span>;<\/span><\/p>\n<p><span style=\"font-weight: 400;\">6) foundFreeIndex++;<\/span><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p><span style=\"font-weight: 400;\">G\u00f6rece\u011finiz \u00fczere hangi sat\u0131r\u0131n hangi s\u0131ra ile \u00e7a\u011fr\u0131ld\u0131\u011f\u0131 duruma g\u00f6re ilgili dizinin bo\u015f yerine yaz\u0131lan de\u011ferlerden birisi di\u011ferini ezebiliyor. Bu probleme multihreaded programlama d\u00fcnyas\u0131nda <em><strong>\u201crace condition\u201d <\/strong><\/em>(Yar\u0131\u015f Ko\u015fulu)\u00a0denilmektedir. Ortak kaynaklara eri\u015filmesi durumunda, bu tarz problemler olu\u015fabilmektedir. Tabi bu problem her zaman olu\u015facak diye bir durum da yok (inan\u0131n bana olu\u015fmas\u0131 ve bunlar\u0131 yakalamak sizler i\u00e7in \u00e7ok daha hay\u0131rl\u0131 :). Uygulamada bu tarz problemlere yol a\u00e7abilecek k\u0131s\u0131mlara da <em><strong>\u201ccritical section\u201d <\/strong><\/em>(Kritik B\u00f6l\u00fcm)\u00a0denilir. \u00d6zellikle, bu yar\u0131\u015f ko\u015fullar\u0131n\u0131 bulmak her zaman bu kadar kolay olamayabiliyor, \u00e7\u00fcnk\u00fc her zaman olu\u015fmuyorlar. Bu problemleri \u00f6nlemek i\u00e7in, kritik b\u00f6l\u00fcmleri koruma alt\u0131na al\u0131yoruz. Burada \u00f6zellikle dikkat etmenizi istedi\u011fim konu: kaynaklara olan eri\u015fimde, e\u011fer her parti sadece okuma yap\u0131yorsa, herhangi bir s\u0131k\u0131nt\u0131 olmaz ve emniyetli bir \u015fekilde hepsi okuma yapabilir. Ama en az bir taraf, bu veriler \u00fczerine yazma i\u015flemi yapacak ise, i\u015fte \u00e7ar\u015f\u0131 o zaman kar\u0131\u015f\u0131yor. Bunu da not alal\u0131m bir kenara.<\/span><\/p>\n<p><img decoding=\"async\" src=\"https:\/\/images.unsplash.com\/photo-1517088510108-1f4e04f3e8fc?ixlib=rb-1.2.1&amp;ixid=eyJhcHBfaWQiOjEyMDd9&amp;auto=format&amp;fit=crop&amp;w=1000&amp;q=80\" \/><\/p>\n<p id=\"DrElzXZ\">Yukar\u0131daki \u00f6rnekte olu\u015fabilecek olan bir probleme g\u00f6z att\u0131k, peki kritik b\u00f6l\u00fcmleri koruma alt\u0131na almazsak ne tarz problemler ile kar\u015f\u0131la\u015fabiliriz? Hemen bakal\u0131m:<\/p>\n<ul>\n<li style=\"font-weight: 400;\"><b>Senkronize Olmayan Veri Eri\u015fimi (\u201c<em>Unsynchronized Data Access&#8221;<\/em>)<\/b><span style=\"font-weight: 400;\">: Asl\u0131nda yukar\u0131da verdi\u011fimiz \u00f6rnek bu gruba girmekte. Birden fazla thread paralel bir \u015fekilde, ortak bir veriye okuma ve yazma yap\u0131yor ise hangisinin \u00f6nce yazd\u0131\u011f\u0131 problemi ortaya \u00e7\u0131kabilir.<\/span><\/li>\n<li style=\"font-weight: 400;\"><b>Yar\u0131 Yaz\u0131lm\u0131\u015f Veri (<em>\u201cHalf-written Data\u201d<\/em>)<\/b><span style=\"font-weight: 400;\">: Benzer \u015fekilde bir thread veriye yaz\u0131yorken, di\u011fer thread onu tam da yazma i\u015fleminin <\/span><i><span style=\"font-weight: 400;\">ortas\u0131nda <\/span><\/i><span style=\"font-weight: 400;\">okuyabilir. Elinde ne eski ne de yeni veri olabilir \ud83d\ude42 Bunu da \u00e7ok basit bir \u00f6rnek ile anlatmaya \u00e7al\u0131\u015fay\u0131m: elimizde a\u015fa\u011f\u0131daki gibi bir kod bildirimi oldu\u011funu d\u00fc\u015f\u00fcnelim:<\/span><\/li>\n<\/ul>\n<p style=\"text-align: left;\"><strong>long long x = 0;<\/strong><\/p>\n<p style=\"text-align: left;\"><span style=\"font-weight: 400;\">Bir thread bu veriyi a\u015fa\u011f\u0131daki gibi de\u011fi\u015ftiriyor:<\/span><\/p>\n<p style=\"text-align: left;\"><strong>x = -1;<\/strong><\/p>\n<p style=\"text-align: left;\"><span style=\"font-weight: 400;\">Di\u011feri de a\u015fa\u011f\u0131daki gibi okuyor:<\/span><\/p>\n<p style=\"text-align: left;\"><strong>std::cout &lt;&lt; x;<\/strong><\/p>\n<p style=\"text-align: left;\"><span style=\"font-weight: 400;\">\u0130\u015fte tam bahsetti\u011fimiz probleme \u00f6rnek olabilecek bir durum.<\/span><\/p>\n<ul>\n<li>\n<p style=\"text-align: left;\"><b>S\u0131ralar\u0131 De\u011fi\u015ftirilmi\u015f Kod Bildirimleri (\u201c<em>Reordered Statements<\/em>\u201d)<\/b><span style=\"font-weight: 400;\">: Ayr\u0131 ayr\u0131 threadlerdeki kod bildirimleri, performans veya benzeri sebeplerle de\u011fi\u015ftirilmi\u015f olabilirler. Bunlar her ne kadar tek ba\u015flar\u0131na s\u0131k\u0131nt\u0131 olmasalar da (s\u0131ral\u0131 ko\u015fturma), paralel ko\u015fumlarda, beklenen davran\u0131\u015f g\u00f6zlemlenmeyecektir.<\/span><\/p>\n<\/li>\n<\/ul>\n<p><span style=\"font-weight: 400;\">Bu konulara ili\u015fkin daha detayl\u0131 bilgiler i\u00e7in (\u00f6zellikle bu tarz problemler ve yakla\u015f\u0131mlar i\u00e7in), ilk yaz\u0131mda bahsetti\u011fim a\u015fa\u011f\u0131daki kitaplara bir g\u00f6z atabilirsiniz:<\/span><\/p>\n<ul>\n<li><strong><span style=\"color: #008000;\"><a style=\"color: #008000;\" href=\"https:\/\/www.amazon.com\/Modern-Operating-Systems-Andrew-Tanenbaum\/dp\/013359162X\">Tanenbaum\u2019s Modern Operating Systems book<\/a><\/span><\/strong><\/li>\n<li><strong><span style=\"color: #008000;\"><a style=\"color: #008000;\" href=\"https:\/\/www.amazon.com\/C-Concurrency-Action-Anthony-Williams\/dp\/1617294691\/ref=pd_lpo_sbs_14_img_0?_encoding=UTF8&amp;psc=1&amp;refRID=ZXET66SHQDZSWECSTNBQ\">Anthony Williams C++ Concurreny in Action books<\/a>.<\/span><\/strong><\/li>\n<\/ul>\n<p><span style=\"font-weight: 400;\">\u015eimdi bu yap\u0131lardan ilki olan <em>std::mutex<\/em>\u2019lere bakal\u0131m.\u00a0<\/span><\/p>\n<h2><span style=\"color: #0000ff;\"><b>std::mutex:<\/b><\/span><\/h2>\n<p><span style=\"font-weight: 400;\">Mutex\u2019ler, \u201cmutual exclusion\u201d olarak da bilinir, bir kayna\u011fa olan e\u015f zamanl\u0131 eri\u015fim ihtiyac\u0131n\u0131, o kayna\u011fa \u00f6zel eri\u015fim sunarak sa\u011flayan yap\u0131lara denir. Burada taraflar ilgili kayna\u011fa eri\u015fmek i\u00e7in <em>std::mutex<\/em> \u00fczerinden kilitleme i\u015fini yapar ve \u00a0kayna\u011fa eri\u015fir, bu s\u0131rada di\u011fer threadlerin bu kayna\u011fa eri\u015fimi engellenir. Ta ki, ilgili taraf bu kilidi kald\u0131rana kadar. \u0130<\/span><span style=\"font-weight: 400;\">lk olarak Edsger W. Dijsktra taraf\u0131ndan tan\u0131mlanm\u0131\u015ft\u0131r. Basit\u00e7e asl\u0131nda payla\u015f\u0131lan kayna\u011fa, tek eri\u015fimi sa\u011flayan en temel senkronizasyon yap\u0131s\u0131d\u0131r.<\/span><\/p>\n<p><span style=\"font-weight: 400;\"><em>std::mutex<\/em> s\u0131n\u0131f\u0131n\u0131 kullanabilmek i\u00e7in \u2018&lt;mutex&gt;\u2019 ba\u015fl\u0131k dosyas\u0131n\u0131 eklemeniz gerekmekte. Bu k\u00fct\u00fcphane alt\u0131nda mutex \u00a0anlam\u0131nda kullanabilece\u011finiz \u00f6nemli s\u0131n\u0131flar\u0131 ve hangi C++ ile kullan\u0131ma sunulduklar\u0131n\u0131, a\u015fa\u011f\u0131daki k\u0131sa a\u00e7\u0131klamalar ile \u00f6zetlemeye \u00e7al\u0131\u015ft\u0131m. Bunlara ili\u015fkin referans bilgilerine bu adresten ula\u015fabilirsiniz. Sonras\u0131nda bunlar\u0131na kullan\u0131m\u0131na hep birlikte \u00f6rnek kodlar \u00fczerinden bakaca\u011f\u0131z. Daha detayl\u0131 \u00f6rnek ve kullan\u0131mlar i\u00e7in ise, kaynaklar\u0131n adreslerini en son b\u00f6l\u00fcmde verece\u011fim. <\/span><\/p>\n<p>&nbsp;<\/p>\n<table>\n<tbody>\n<tr>\n<td style=\"text-align: center;\" colspan=\"2\"><strong>Temel mutex S\u0131n\u0131flar\u0131 &#8211; I<\/strong><\/td>\n<\/tr>\n<tr>\n<td><span style=\"color: #008000;\"><a style=\"color: #008000;\" href=\"https:\/\/en.cppreference.com\/w\/cpp\/thread\/mutex\"><b>std::mutex<\/b><\/a><\/span>\u00a0<span style=\"font-weight: 400;\">(C++11)<\/span><\/td>\n<td><span style=\"font-weight: 400;\">Temel kar\u015f\u0131l\u0131kl\u0131 d\u0131\u015flama (mutual exclusion)\/g\u00fcvenli eri\u015fim kabiliyeti sunar\u00a0<\/span><\/td>\n<\/tr>\n<tr>\n<td><a href=\"https:\/\/en.cppreference.com\/w\/cpp\/thread\/mutex\"><b><span style=\"color: #008000;\">std::<\/span><\/b><\/a><span style=\"color: #008000;\"><a style=\"color: #008000;\" href=\"https:\/\/en.cppreference.com\/w\/cpp\/thread\/timed_mutex\"><b>timed_mutex<\/b><\/a><\/span>\u00a0<span style=\"font-weight: 400;\">(C++11)<\/span><\/td>\n<td><span style=\"font-weight: 400;\">Kar\u015f\u0131l\u0131kl\u0131 d\u0131\u015flama (mutual exclusion)\/g\u00fcvenli eri\u015fim kabiliyetini s\u00fcreli bir \u015fekilde sunar<\/span><\/td>\n<\/tr>\n<tr>\n<td><a href=\"https:\/\/en.cppreference.com\/w\/cpp\/thread\/recursive_mutex\"><b><span style=\"color: #008000;\">recursive_mutex<\/span><\/b><\/a>\u00a0<span style=\"font-weight: 400;\">(C++11)<\/span><\/td>\n<td><span style=\"font-weight: 400;\">Kar\u015f\u0131l\u0131kl\u0131 d\u0131\u015flama (mutual exclusion)\/g\u00fcvenli eri\u015fim kabiliyetini, ayn\u0131 thread i\u00e7in yineli bir \u015fekilde ger\u00e7ekle\u015ftirilmesine olanak sa\u011flar<\/span><\/td>\n<\/tr>\n<tr>\n<td><a href=\"https:\/\/en.cppreference.com\/w\/cpp\/thread\/recursive_timed_mutex\"><b><span style=\"color: #008000;\">recursive_timed_mutex<\/span><\/b><\/a><\/p>\n<p><span style=\"font-weight: 400;\"><span style=\"color: #008000;\">(<\/span>C++11)<\/span><\/td>\n<td><span style=\"font-weight: 400;\">Kar\u015f\u0131l\u0131kl\u0131 d\u0131\u015flama (mutual exclusion)\/g\u00fcvenli eri\u015fim kabiliyetini, ayn\u0131 thread i\u00e7in yineli ve verilen zaman i\u00e7in ger\u00e7ekle\u015ftirilecek \u015fekilde yap\u0131labilmesine olanak sa\u011flar<\/span><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>&nbsp;<\/p>\n<table>\n<tbody>\n<tr>\n<td><a href=\"https:\/\/en.cppreference.com\/w\/cpp\/thread\/lock_guard\"><b><span style=\"color: #008000;\">lock_guard<\/span><\/b><\/a><\/p>\n<p><span style=\"font-weight: 400;\">(C++11)<\/span><\/td>\n<td><span style=\"font-weight: 400;\">RAII (Resource Acquisition Is Initialization) mekanizmas\u0131na uygun bir \u015fekilde mutex kullan\u0131larak verilen kapsam i\u00e7in kar\u015f\u0131l\u0131kl\u0131 d\u0131\u015flama kabiliyeti sunar.Asl\u0131nda arka planda yap\u0131lan \u015fey, yap\u0131c\u0131 i\u00e7erisinde ilgili mutex\u2019i kilitlemek ve kapsam d\u0131\u015f\u0131nda \u00e7\u0131kan scoped_lock nesnesi ile \u00e7a\u011fr\u0131lacak y\u0131k\u0131c\u0131 i\u00e7erisinde de bu kilidi geri a\u00e7mak.<\/span><\/td>\n<\/tr>\n<tr>\n<td><a href=\"https:\/\/en.cppreference.com\/w\/cpp\/thread\/unique_lock\"><b><span style=\"color: #008000;\">unique_lock<\/span><\/b><\/a><\/p>\n<p><span style=\"font-weight: 400;\">(C++11)<\/span><\/td>\n<td><span style=\"font-weight: 400;\">Kar\u015f\u0131l\u0131kl\u0131 d\u0131\u015flamay\u0131 i\u00e7erisinde bar\u0131nd\u0131ran ve sahipli\u011fini ta\u015f\u0131ma yolu ile aktarabilece\u011finiz mekanizmay\u0131 sunan s\u0131n\u0131ft\u0131r<\/span><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>&nbsp;<\/p>\n<table>\n<tbody>\n<tr>\n<td colspan=\"2\">\n<p style=\"text-align: center;\"><b>Kullan\u0131ma Sunulan Baz\u0131 Ba\u011f\u0131ms\u0131z Fonksiyonlar<\/b><\/p>\n<\/td>\n<\/tr>\n<tr>\n<td><a href=\"https:\/\/en.cppreference.com\/w\/cpp\/thread\/try_lock\"><b><span style=\"color: #008000;\">try_lock\u00a0<\/span><\/b><\/a><b>(C++11)<\/b><\/td>\n<td><span style=\"font-weight: 400;\">Metoda ge\u00e7irilen kilitlenebilir nesnelerin, hepsini kitlemeye \u00e7al\u0131\u015f\u0131r. Kilitleyemedi\u011fi ilk nesnenin indeksini d\u00f6ner. Ba\u015far\u0131l\u0131 durumda -1 d\u00f6n\u00fcl\u00fcr.<\/span><\/p>\n<p>&nbsp;<\/td>\n<\/tr>\n<tr>\n<td><a href=\"https:\/\/en.cppreference.com\/w\/cpp\/thread\/lock\"><b><span style=\"color: #008000;\">lock\u00a0<\/span><\/b><\/a><b>(C++11)<\/b><\/td>\n<td><span style=\"font-weight: 400;\">Metoda ge\u00e7irilen kitlenebilir nesneleri kilitler, e\u011fer kilitleyemez ise mevcut thread\u2019i bloklar<\/span><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>&nbsp;<\/p>\n<p><span style=\"font-weight: 400;\">\u0130lk yaz\u0131mda da bahsetti\u011fim gibi, <em>std::thread<\/em> k\u00fct\u00fcphanesi asl\u0131nda ilk olarak C++ 11 ile sunulmaya ba\u015fland\u0131, yukar\u0131daki bahsetti\u011fim s\u0131n\u0131flar da \u00f6le. C++ 14 ve 17 ile de a\u015fa\u011f\u0131daki gibi bir tak\u0131m eklemeler oldu:<\/span><\/p>\n<table>\n<tbody>\n<tr>\n<td style=\"text-align: center;\" colspan=\"2\"><span style=\"font-weight: 400;\"><strong>Temel Mutex S\u0131n\u0131flar\u0131 II<\/strong><\/span><\/td>\n<\/tr>\n<tr>\n<td><a href=\"https:\/\/en.cppreference.com\/w\/cpp\/thread\/shared_mutex\"><b><span style=\"color: #008000;\">shared_mutex<\/span><\/b><\/a><\/p>\n<p><span style=\"font-weight: 400;\">(C++17)<\/span><\/td>\n<td><span style=\"font-weight: 400;\">Temel kar\u015f\u0131l\u0131kl\u0131 d\u0131\u015flama (mutual exclusion) kabiliyetinin bir \u00e7ok nesne taraf\u0131ndan payla\u015f\u0131labilmesine olanak sa\u011flar. \u00d6zellikle ayn\u0131 anda birden fazla okuma ve yaz yap\u0131labilece\u011fi durumlarda, okumalar esnas\u0131nda kullan\u0131c\u0131lar\u0131n herhangi bir bloklama olmadan veriye eri\u015fmelerine olanak sa\u011flar,<\/span><\/td>\n<\/tr>\n<tr>\n<td><a href=\"https:\/\/en.cppreference.com\/w\/cpp\/thread\/shared_timed_mutex\"><b><span style=\"color: #008000;\">shared_timed_mutex<\/span><\/b><\/a><\/p>\n<p><span style=\"font-weight: 400;\">(C++14)<\/span><\/td>\n<td><span style=\"font-weight: 400;\">Bir \u00f6nceki s\u0131n\u0131f\u0131n, belirli bir s\u00fcre i\u00e7in bu kilitlerin tutulabilmesine olanak sa\u011flayan s\u0131n\u0131f\u0131<\/span><\/td>\n<\/tr>\n<tr>\n<td><a href=\"https:\/\/en.cppreference.com\/w\/cpp\/thread\/scoped_lock\"><b><span style=\"color: #008000;\">scoped_lock<\/span><\/b><\/a><\/p>\n<p>(C++17)<\/td>\n<td><span style=\"font-weight: 400;\">RAII (Resource Acquisition Is Initialization) mekanizmas\u0131na uygun bir \u015fekilde, bir ya da birden fazla mutex kullan\u0131larak verilen kapsam i\u00e7in kar\u015f\u0131l\u0131kl\u0131 d\u0131\u015flama kabiliyeti sunar. Lock_guard\u2019tan fark\u0131, birden fazla mutex\u2019i alabilmesidir. Bu kullan\u0131ma ili\u015fkin bir \u00f6rnek a\u015fa\u011f\u0131daki adreste verilmekte:<\/span><\/p>\n<p><strong><span style=\"color: #008000;\"><a style=\"color: #008000;\" href=\"https:\/\/stackoverflow.com\/questions\/17113619\/whats-the-best-way-to-lock-multiple-stdmutexes\/17113678\">https:\/\/stackoverflow.com\/questions\/17113619\/whats-the-best-way-to-lock-multiple-stdmutexes\/17113678<\/a><\/span><\/strong><\/td>\n<\/tr>\n<tr>\n<td><strong><span style=\"color: #008000;\"><a style=\"color: #008000;\" href=\"https:\/\/en.cppreference.com\/w\/cpp\/thread\/shared_lock\">shared_lock<\/a><\/span><\/strong><\/p>\n<p>(C++14)<\/td>\n<td><span style=\"font-weight: 400;\">Verilen payla\u015f\u0131ml\u0131 mutex i\u00e7in, ta\u015f\u0131nabilir sahiplik ve bir \u00f6nceki s\u0131n\u0131ftakine benzer kabiliyetler sunar<\/span><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>&nbsp;<\/p>\n<p><span style=\"font-weight: 400;\">Evet, elimizdeki cephanenin neler oldu\u011funu \u00f6\u011frendi\u011fimize g\u00f6re, \u015fimdi bunlar\u0131 nas\u0131l kullanabilece\u011fimize bir g\u00f6z atal\u0131m.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u0130lk \u00f6rne\u011fimiz, multi-threaded yaz\u0131l\u0131m geli\u015ftirirken, eminim hepiniz, konsola bir \u015feyler bast\u0131rmak istemi\u015fsinizdir ve ilk tecr\u00fcbe etti\u011finiz deneyim de karmakar\u0131\u015f\u0131k \u00e7\u0131kt\u0131lar olacakt\u0131r muhtemelen. Gelin bunu, yukar\u0131daki temel yap\u0131lar\u0131 kullanarak basit\u00e7e nas\u0131l \u00e7\u00f6zebilece\u011fimize bakal\u0131m. Tahmin edebilece\u011finiz \u00fczere, bu durumdaki payla\u015f\u0131lan kaynak standart \u00e7\u0131kt\u0131 ak\u0131\u015f\u0131 (&#8220;<em>standard output stream<\/em>&#8220;).<\/span><\/p>\n<pre class=\"lang:c++ decode:true\">#include &lt;thread&gt;\r\n#include &lt;mutex&gt;\r\n#include &lt;iostream&gt;\r\n#include &lt;string&gt;\r\n#include &lt;chrono&gt;\r\n\r\n\/\/ Ortak veri payla\u015f\u0131m\u0131 (ki burada standard output) i\u00e7in muteximiz\r\nstd::mutex gPrintMutex;\r\n\r\nvoid threadSafePrintVersion1(const std::string&amp; input)\r\n{\r\n    gPrintMutex.lock();\r\n    for(auto c : input)\r\n    {    \r\n        std::cout.put(c);\r\n\t    std::this_thread::sleep_for(std::chrono::milliseconds(1));\r\n    }\r\n\tgPrintMutex.unlock();\r\n}\r\n\r\nvoid threadSafePrintVersion2(const std::string&amp; input)\r\n{\r\n    std::lock_guard&lt;std::mutex&gt; localLock(gPrintMutex);\r\n    for(auto c : input)\r\n    {    \r\n        std::cout.put(c);\r\n\t    std::this_thread::sleep_for(std::chrono::milliseconds(1));\r\n    }\r\n}\r\n\r\nint main()\r\n{\r\n\tstd::thread firstThread(threadSafePrintVersion1, \"Hello world from thread 1!\\n\");\r\n\tstd::thread secondThread(threadSafePrintVersion2, \"Hello world from thread 2!\\n\");\r\n\tstd::cout &lt;&lt; \"Hello world from main thread!\\n\";\r\n\t\r\n\tfirstThread.join();\r\n\tsecondThread.join();\r\n\r\n\treturn 0;\r\n}<\/pre>\n<p><span style=\"font-weight: 400;\">Yukar\u0131da verilen kodta her iki metot da ayn\u0131 i\u015fi yapmakta. Fakat <em>std::scoped_lock<\/em> daha okunakl\u0131 (tabi bana g\u00f6re \ud83d\ude42 hem de direk <em>std::mutex<\/em> kullan\u0131m\u0131 durumunda ortaya \u00e7\u0131kabilecek <em>unlock()<\/em> unutmak ya da gereksiz <em>lock()<\/em>\u00a0\u00e7a\u011fr\u0131lmas\u0131 benzeri problemleri bertaraf etmekte. Burada tabi s\u0131k\u0131nt\u0131l\u0131 durumu ortaya koymak i\u00e7in koda bir tak\u0131m eklemeler (bekleme ve put API\u2019lerinin kullan\u0131m\u0131) yapt\u0131m \ud83d\ude42 Normalde basit uygulamalarda <em>std::cout<\/em> bunu s\u0131k\u0131nt\u0131 ya\u015famadan g\u00f6r\u00fcnt\u00fcleyebilir. Ama yukar\u0131daki mutex\u2019ler ile ilgili sat\u0131rlar\u0131 yorumlad\u0131\u011f\u0131n\u0131zda neler oldu\u011funu g\u00f6rebilirsiniz. <\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u015eimdi de, ilk durum kadar olmasa da, <em>std::recursive_lock<\/em> kullanman\u0131z\u0131 gerektirecek durumlara bir g\u00f6z atal\u0131m. Bu ihtiya\u00e7, genellikle her bir metodu i\u00e7erisinde mutex kullan\u0131lan ve bu metotlar\u0131n birbirlerini \u00e7a\u011f\u0131rmalar\u0131 gerekti\u011fi durumlarda ortaya \u00e7\u0131kar. Hemen bir \u00f6rne\u011fe bakal\u0131m:<\/span><\/p>\n<pre class=\"lang:c++ decode:true \">struct Calculator\r\n{\r\n    std::mutex mMutex;\r\n    int mLastResult;\r\n\r\n    Calculator() : i(0) {}\r\n\r\n    void multiply(int x)\r\n    {\r\n        std::lock_guard&lt;std::mutex&gt; lock{mMutex};\r\n        mLastResult *= x;\r\n    }\r\n\r\n    void divide(int x)\r\n    {\r\n        std::lock_guard&lt;std::mutex&gt; lock{mMutex};\r\n        mLastResult \/= x;\r\n    }\r\n\r\n\t\/\/ Yukar\u0131daki her iki metodu da cagirmamiz gerekecek!\r\n\tvoid both(int x, int y)\r\n\t{\r\n\t    std::lock_guard&lt;std::mutex&gt; lock{mMutex};\r\n\t    multiply(x);\r\n\t    divide(y);\r\n\t}\r\n};\r\n\r\nint main()\r\n{\r\n    Complex complex;\r\n    complex.both(32, 23);\r\n\r\n    return 0;\r\n}<\/pre>\n<p><span style=\"font-weight: 400;\">Bu \u00f6rnekte g\u00f6rd\u00fc\u011f\u00fcn\u00fcz gibi tek tek multiply() ya da divide() metotlar\u0131n\u0131 \u00e7a\u011f\u0131rd\u0131\u011f\u0131n\u0131z zaman herhangi bir problem ile kar\u015f\u0131la\u015fmayacaks\u0131n\u0131z. Fakat both() metodunu \u00e7a\u011f\u0131rd\u0131\u011f\u0131n\u0131zda uygulama bloklanacak, sizce neden?<\/span><\/p>\n<p><img decoding=\"async\" src=\"https:\/\/images.unsplash.com\/photo-1534418302821-e614748fcae9?ixlib=rb-1.2.1&amp;auto=format&amp;fit=crop&amp;w=1000&amp;q=80\" \/><\/p>\n<p><span style=\"font-weight: 400;\">both() metodu, <em>mMutex<\/em> kilidini ba\u015fta kilitliyor, daha sonra multiply()\u2019\u0131 \u00e7a\u011f\u0131rd\u0131\u011f\u0131m\u0131zda ise ayn\u0131 kilidi kilitlemeye \u00e7al\u0131\u015ft\u0131\u011f\u0131nda, \u201cdeadlock\u201d dedi\u011fimiz duruma sebebiyet vermi\u015f oluyoruz. Ayn\u0131 thread, bir mutex\u2019i iki kere kilitleyemez. \u015eimdi <em>std::mutex<\/em> kullan\u0131mlar\u0131n\u0131n hepsini, <em>std::recursive_mutex<\/em> ile de\u011fi\u015ftirelim ve \u00f6yle \u00e7al\u0131\u015ft\u0131ral\u0131m, bu durumda herhangi bir problem olmad\u0131\u011f\u0131n\u0131 g\u00f6receksiniz.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">Yukar\u0131daki kullan\u0131mlarda, e\u011fer ilgili mutex zaten kilitli ise ilgili thread bloklan\u0131r. Bunun yerine ilgili mutex\u2019i kilitleyip\/kilitleyemedi\u011finizi sorgulamak isteyebilirsiniz. Bu durumda <em>try_lock()<\/em> ve t\u00fcrevlerini kullanabilirsiniz. Hemen bir \u00f6rnek kullan\u0131m\u0131na (referans sayfas\u0131ndan) bakal\u0131m:<\/span><\/p>\n<pre class=\"lang:c++ decode:true \">\/\/ try_lock\r\n#include &lt;chrono&gt;\r\n#include &lt;mutex&gt;\r\n#include &lt;thread&gt;\r\n#include &lt;iostream&gt; \/\/ std::cout\r\n \r\nstd::chrono::milliseconds interval(100);\r\n \r\nstd::mutex mutex;\r\nint job_shared = 0; \/\/ both threads can modify 'job_shared',\r\n    \/\/ mutex will protect this variable\r\n \r\nint job_exclusive = 0; \/\/ only one thread can modify 'job_exclusive'\r\n    \/\/ no protection needed\r\n \r\n\/\/ this thread can modify both 'job_shared' and 'job_exclusive'\r\nvoid job_1() \r\n{\r\n    std::this_thread::sleep_for(interval); \/\/ let 'job_2' take a lock\r\n \r\n    while (true) \r\n    {\r\n        \/\/ try to lock mutex to modify 'job_shared'\r\n        if (mutex.try_lock()) \r\n        {\r\n            std::cout &lt;&lt; \"job shared (\" &lt;&lt; job_shared &lt;&lt; \")\\n\";\r\n            mutex.unlock();\r\n            return;\r\n        } \r\n        else \r\n        {\r\n            \/\/ can't get lock to modify 'job_shared'\r\n            \/\/ but there is some other work to do\r\n            ++job_exclusive;\r\n            std::cout &lt;&lt; \"job exclusive (\" &lt;&lt; job_exclusive &lt;&lt; \")\\n\";\r\n            std::this_thread::sleep_for(interval);\r\n        }\r\n    }\r\n}\r\n \r\n\/\/ this thread can modify only 'job_shared'\r\nvoid job_2() \r\n{\r\n    mutex.lock();\r\n    std::this_thread::sleep_for(5 * interval);\r\n    ++job_shared;\r\n    mutex.unlock();\r\n}\r\n \r\nint main() \r\n{\r\n    std::thread thread_1(job_1);\r\n    std::thread thread_2(job_2);\r\n \r\n    thread_1.join();\r\n    thread_2.join();\r\n}<\/pre>\n<p><span style=\"font-weight: 400;\">\u015eimdi bir di\u011fer kullan\u0131ma daha g\u00f6z atal\u0131m ve sonras\u0131nda mutex sayfas\u0131n\u0131 kapatal\u0131m. Bu kullan\u0131m, <em>std::timed_mutex<\/em>\u2019ler ile ilgili. Bu s\u0131n\u0131f standart <em>std::mutex<\/em>\u2019in API\u2019leri yan\u0131nda try_lock_for ve try_lock_until API\u2019lerini sunar. try_lock_for() API\u2019si, verilen mutex\u2019i kilitlemeye \u00e7al\u0131\u015f\u0131r, e\u011fer bu mutex kilitli ise, sonsuza kadar beklemek yerine, verilen s\u00fcre kadar bu mutex\u2019in kilidinin a\u00e7\u0131lmas\u0131n\u0131 bekler. E\u011fer alabilirse, <em>true<\/em> d\u00f6ner, alamaz ise <em>false<\/em> d\u00f6ner. try_lock_until\u2019de buna benzer bir kullan\u0131m sunar, tek fark\u0131 s\u00fcre yerine direk zaman verilmesidir. Yine referans sayfas\u0131nda verilen \u00f6rne\u011fe bakal\u0131m:<\/span><\/p>\n<pre class=\"lang:c++ decode:true \">#include &lt;iostream&gt;\r\n#include &lt;mutex&gt;\r\n#include &lt;thread&gt;\r\n#include &lt;vector&gt;\r\n#include &lt;sstream&gt;\r\n \r\nstd::mutex cout_mutex; \/\/ control access to std::cout\r\nstd::timed_mutex mutex;\r\n \r\nvoid job(int id) \r\n{\r\n    using Ms = std::chrono::milliseconds;\r\n    std::ostringstream stream;\r\n \r\n    for (int i = 0; i &lt; 3; ++i) {\r\n        if (mutex.try_lock_for(Ms(100))) {\r\n            stream &lt;&lt; \"success \";\r\n            std::this_thread::sleep_for(Ms(100));\r\n            mutex.unlock();\r\n        } else {\r\n            stream &lt;&lt; \"failed \";\r\n        }\r\n        std::this_thread::sleep_for(Ms(100));\r\n    }\r\n \r\n    std::lock_guard&lt;std::mutex&gt; lock(cout_mutex);\r\n    std::cout &lt;&lt; \"[\" &lt;&lt; id &lt;&lt; \"] \" &lt;&lt; stream.str() &lt;&lt; \"\\n\";\r\n}\r\n \r\nint main() \r\n{\r\n    std::vector&lt;std::thread&gt; threads;\r\n    for (int i = 0; i &lt; 4; ++i) {\r\n        threads.emplace_back(job, i);\r\n    }\r\n \r\n    for (auto&amp; i: threads) {\r\n        i.join();\r\n    }\r\n}<\/pre>\n<p><span style=\"font-weight: 400;\">Bazen bir metodun, farkl\u0131 thread\u2019lerden sadece bir kere \u00e7a\u011fr\u0131lmas\u0131n\u0131 isteyebilirsiniz. Bu k\u00fct\u00fcphane bu tarz durumlar i\u00e7in de <em>std::call_once<\/em> fonksiyonunu sunuyor. Buna ili\u015fkin de bir \u00f6rne\u011fe bakal\u0131m:<\/span><\/p>\n<pre class=\"lang:c++ decode:true\">std::once_flag flag;\r\n\r\nvoid do_something()\r\n{\r\n    std::call_once(flag, [](){std::cout &lt;&lt; \"Called once\" &lt;&lt; '\\n';});\r\n    std::cout &lt;&lt; \"Called each time\" &lt;&lt; '\\n';\r\n}\r\n\r\nint main(){\r\n    std::thread t1(do_something);\r\n    std::thread t2(do_something);\r\n    std::thread t3(do_something);\r\n    std::thread t4(do_something);\r\n\r\n    t1.join();\r\n    t2.join();\r\n    t3.join();\r\n    t4.join();\r\n\r\n    return 0;\r\n}<\/pre>\n<p><span style=\"font-weight: 400;\">Yukar\u0131da verdi\u011fim \u00f6rnek kod i\u00e7erisindeki, doSomenthing() metodunun ilk k\u0131sm\u0131, kullan\u0131lan ilgili <em>std::once_flag<\/em> sayesinde sadece bir kere \u00e7a\u011fr\u0131l\u0131yor olacak.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">Bu kullan\u0131m ile birlikte mutex\u2019lere ili\u015fkin baya bir konuyu i\u015flemi\u015f olduk. Daha bir \u015fey kalmad\u0131 m\u0131? Elbette bir \u00e7ok konu daha var (daha detayl\u0131 bilgi i\u00e7in kaynaklara bir g\u00f6z atabilirsiniz, ya da her zaman google&#8217;a dan\u0131\u015fabilirsiniz \ud83d\ude42 ama bence bunlar size ba\u015flang\u0131\u00e7 i\u00e7in yeterli olacakt\u0131r. Bir sonraki ba\u015fl\u0131kta bir di\u011fer \u00f6nemli yap\u0131 olan <em>std::condition_variable<\/em>\u2019lara bakaca\u011f\u0131z.<\/span><\/p>\n<h2><span style=\"color: #0000ff;\"><b>std::condition_variable:<\/b><\/span><\/h2>\n<p><span style=\"font-weight: 400;\">Thread k\u00fct\u00fcphanesi ile sunulan bir di\u011fer \u00f6nemli yap\u0131 da <em>std::condition_variable<\/em>\u2019d\u0131r. \u00d6zellikle multithreaded yaz\u0131l\u0131m geli\u015ftirdi\u011finiz durumlarda, bir thread\u2019in di\u011ferini beklemesi, onun yapt\u0131\u011f\u0131 i\u015f ya da bir ko\u015ful sa\u011fland\u0131\u011f\u0131 zaman \u00e7al\u0131\u015fmaya devam etmesi gibi durumlar ile kar\u015f\u0131la\u015fm\u0131\u015fs\u0131n\u0131zd\u0131r. \u0130\u015fte tam da bu gibi durumlar i\u00e7in <em>std::conditional_variable<\/em> yap\u0131lar\u0131 kullan\u0131labilir. Burada tabi, bir thread\u2019ten veri almak i\u00e7in <em>std::future<\/em> mekanizmas\u0131n\u0131n kullan\u0131labilece\u011fini s\u00f6yleyebilirsiniz, do\u011frudur, fakat <em>std::future<\/em>\u2019lar\u0131n tek amac\u0131 farkl\u0131 bir thread\u2019ten veri d\u00f6nd\u00fcr\u00fclmesi ya da hatal\u0131 durumun bildirilmesi oldu\u011fu i\u00e7in baz\u0131 durumlarda daha g\u00fc\u00e7l\u00fc bir mekanizmaya ihtiya\u00e7 duyabiliriz.<\/span><\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter\" src=\"https:\/\/cdn.pixabay.com\/photo\/2014\/08\/05\/10\/31\/waiting-410328_960_720.jpg\" alt=\"Waiting, Appointment, Schedule, Time, Hurry, Urgent\" width=\"581\" height=\"387\" \/><\/p>\n<p><span style=\"font-weight: 400;\">Daha \u00f6nce pek bahsetmedik ama bir thread i\u015fini yaparken di\u011ferine ili\u015fkin durumu asl\u0131nda bir d\u00f6ng\u00fc i\u00e7erisinde bekleyerek de kontrol edebiliriz. Bu yakla\u015f\u0131m \u201cbusy wait\u201d ya da \u201cpolling\u201d de deniliyor. Hemen bir \u00f6rnek \u00fczerinden bu duruma bir g\u00f6z atal\u0131m:<\/span><\/p>\n<pre class=\"lang:c++ decode:true\">#include &lt;thread&gt;\r\n#include &lt;mutex&gt;\r\n#include &lt;chrono&gt;\r\n\r\n\/\/ Durum 1: Iyimser bir kontrol durumu\r\nbool isReady {false};\r\nstd::mutex isReadyMutex;\r\n\r\n\/\/ Burada ilgili isReady de\u011fi\u015fkeni true olana kadar d\u00f6ng\u00fc i\u00e7erisinde bekliyoruz\r\n\/\/ ...\r\n\/\/ unique_lock burada kilitlemeye baslar\r\nstd::unique_lock&lt;std::mutex&gt; loopLock{isReadyMutex};\r\n\r\nwhile(!isReady)\r\n{\r\n\tloopLock.unlock();\r\n\t\/\/ CPU kullanimini bir sonraki thread'e gecirmek icin haber vermek olarak dusunebiliriz \r\n\tstd::this_thread::yield();\r\n\t\/\/ 100 ms sonra tekrar kontrol edelim\r\n\tstd::this_thread::sleep_for(std::chrono::milliseconds(100));\t\r\n\tloopLock.lock();\r\n}<\/pre>\n<p><span style=\"font-weight: 400;\">Burada g\u00f6rd\u00fc\u011f\u00fcn\u00fcz \u00fczere s\u00fcrekli bir kontrol var ve bu her ne kadar k\u00fc\u00e7\u00fck bir i\u015f gibi dursa da, k\u00fc\u00e7\u00fck bekleme s\u00fcreleri sa\u011flamak zor olabilir, daha uzunlar\u0131 i\u00e7in ise gecikmeler ya\u015fanabilir. \u0130\u015fte bunu yerine <em>std::condition_variable<\/em> kullanabilirsiniz. Peki nedir bu yap\u0131lar, hemen <strong><span style=\"color: #008000;\"><a style=\"color: #008000;\" href=\"https:\/\/en.cppreference.com\/w\/cpp\/thread\/condition_variable\">referans dok\u00fcmana<\/a><\/span><\/strong> bakal\u0131m, yine en g\u00fczel tan\u0131m\u0131 kendisi gayet \u00f6z bir \u015fekilde veriyor:<\/span><\/p>\n<p><span style=\"font-weight: 400;\">Bir \u00e7ok thread\u2019in birbirleri ile ileti\u015fim kurmas\u0131na olanak sa\u011flayan bir senkronizasyon yap\u0131s\u0131d\u0131r. Bu yap\u0131 bir ya da daha fazla thread\u2019in, bir ya da fazla thread\u2019i beklemesini (istenirse verilen bir s\u00fcre kadar), daha sonra ise i\u015fine devam etmesini sa\u011flar. <\/span><\/p>\n<p><span style=\"font-weight: 400;\">Her bir ko\u015fullu de\u011fi\u015fkeni muhakkak bir mutex ile ili\u015fkilendirilerek kullan\u0131l\u0131r. Ko\u015fullu de\u011fi\u015fkenlerini kullanmak i\u00e7in \u2018&lt;mutex&gt;\u2019 ve \u2018&lt;condition_variable&gt;\u2019 ba\u015fl\u0131k dosyalar\u0131n\u0131 eklemeniz gerekmekte. Yukar\u0131da verdi\u011fim \u00f6rne\u011fe benzer durumlar i\u00e7in:<\/span><\/p>\n<ul>\n<li style=\"font-weight: 400;\"><span style=\"font-weight: 400;\">Bir ya da birden fazla thread herhangi bir ko\u015fulun sa\u011fland\u0131\u011f\u0131n\u0131 haber vermek i\u00e7in, haber verilecek olan thread say\u0131s\u0131na g\u00f6re:<\/span>\n<ul>\n<li style=\"font-weight: 400;\"><span style=\"font-weight: 400;\"><strong><em>notify_one()<\/em><\/strong> ya da <em><strong>notify_all()<\/strong><\/em> API\u2019lerinden birisini \u00e7a\u011f\u0131r\u0131r<\/span><\/li>\n<\/ul>\n<\/li>\n<li style=\"font-weight: 400;\"><span style=\"font-weight: 400;\">Belirtilen ko\u015fulu beklemek i\u00e7in ya da ondan haberdar olmak i\u00e7in de ilgili thread i\u00e7erisinde:<\/span>\n<ul>\n<li style=\"font-weight: 400;\"><span style=\"font-weight: 400;\"><em><strong>wait()<\/strong><\/em> API\u2019si kullan\u0131l\u0131r.<\/span><\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<p><span style=\"font-weight: 400;\">\u015eimdi ilk verdi\u011fimiz \u00f6rne\u011fi bu API\u2019leri kullanarak yazal\u0131m:<\/span><\/p>\n<pre class=\"lang:c++ decode:true\">#include &lt;mutex&gt;\r\n#include &lt;condition_variable&gt;\r\n\r\nbool isReady {false};\r\nstd::mutex isReadyMutex;\r\nstd::condition_variable isReadyCondVariab;\r\n\r\n\/\/ Bekleyen thread isi bitince asagidaki API'leri cagirmali\r\nisReadyCondVariab.notify_one();\r\n\r\n\/\/ Ilgili isReady kosulu icin bekleyen thread de asagidaki API'yi cagirir\r\nstd::unique_lock&lt;std::mutex&gt; lockCV{isReadyMutex};\r\nisReadyCondVariab.wait(lockCV);<\/pre>\n<p><span style=\"font-weight: 400;\">Burada \u00f6nemli bir durumdan daha bahsetmekte fayda var. \u00d6zellikle bu ko\u015fullu de\u011fi\u015fkenleri zaman zaman ilgili thread bunlar\u0131 tetiklemese de, \u00f6yleymi\u015f gibi bloklamay\u0131 sonland\u0131rabilir. Bu durumlarda ilgili ko\u015fullar\u0131n tekrar kontrol edilmesinde fayda var. <\/span><strong><span style=\"color: #008000;\"><a style=\"color: #008000;\" href=\"http:\/\/www.modernescpp.com\/index.php\/c-core-guidelines-be-aware-of-the-traps-of-condition-variables\">http:\/\/www.modernescpp.com\/index.php\/c-core-guidelines-be-aware-of-the-traps-of-condition-variables<\/a><\/span><\/strong><span style=\"font-weight: 400;\"> sayfas\u0131nda bu durum \u00f6rnekler ile g\u00fczel bir \u015fekilde a\u00e7\u0131klanm\u0131\u015f, oraya bir g\u00f6z atabilirsiniz.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u015eimdi \u00e7oklu thread\u2019 taraf\u0131ndan kullan\u0131labilecek bir kuyruk s\u0131n\u0131f\u0131nda ko\u015fullu de\u011fi\u015fkeni ve di\u011fer senkronizasyon yap\u0131lar\u0131n\u0131n kullan\u0131m\u0131na bir g\u00f6z atal\u0131m.<\/span><\/p>\n<pre class=\"lang:c++ decode:true \">template &lt;typename T&gt;\r\nclass SharedQueue\r\n{\r\npublic:\r\n        \/\/ Y\u0131k\u0131c\u0131\r\n\t~SharedQueue(void)\r\n\t{\r\n\t\tInvalidate();\r\n\t}\r\n\r\n\t\/\/ Kuyruktaki ilk elemani, d\u00f6nebilir ise out \u00fczerinden d\u00f6ner. Eger d\u00f6nemez ise false, \u00f6b\u00fcr t\u00fcrl\u00fc true d\u00f6ner\r\n\tbool tryPop(T&amp; out)\r\n\t{\r\n\t\tstd::lock_guard&lt;uMutex&gt; lock{mMutex};\r\n\t\tif (mQueue.empty() || !mValid)\r\n\t\t\treturn false;\r\n\t\t\r\n\t\tout = std::move(mQueue.front());\r\n\t\tmQueue.pop();\r\n\t\treturn true;\r\n\t}\r\n\r\n\t\/\/ Bir \u00f6nceki metottan farkli olarak e\u011fer kuyrukta bir eleman yok ise gelene kadar bekler\r\n\t\/\/ Basarili olarak out doldurulabilirse true, obur turlu false donulur\r\n\tbool waitPop(T&amp; out)\r\n\t{\r\n\t\tstd::unique_lock&lt;uMutex&gt; lock{mMutex};\r\n\t\tmCondition.wait(lock, [this]()\r\n\t\t{\r\n\t\t\t\/\/ Yukar\u0131da bahsetti\u011fim beklenmedik uyanmalara karsi, buradaki gibi onlem alabilirsiniz.\r\n\t\t\t\/\/ Yani queue hala bos ve gecerli oldugu muddetce beklemeye devam\r\n\t\t\treturn !mQueue.empty() || !mValid;\r\n\t\t});\r\n\t\t\r\n\t\tif (!mValid)\r\n\t\t{\r\n\t\t\treturn false;\r\n\t\t}\r\n\t\tout = std::move(mQueue.front());\r\n\t\tmQueue.pop();\r\n\t\treturn true;\r\n\t}\r\n\r\n\t\/\/ Kuyruga yeni bir eleman ekleyelim\r\n\tvoid push(T value)\r\n\t{\r\n\t\tstd::lock_guard&lt;uMutex&gt; lock{mMutex};\r\n\t\tmQueue.push(std::move(value));\r\n\t\tmCondition.notify_one();\r\n\t}\r\n\r\n\t\/\/ Kuyruk bos mu kontrolu\r\n\tbool empty(void) const\r\n\t{\r\n\t\tstd::lock_guard&lt;uMutex&gt; lock{mMutex};\r\n\t\treturn mQueue.empty();\r\n\t}\r\n\r\n\t\/\/ Kuyrugu bosalt\r\n\tvoid clear(void)\r\n\t{\r\n\t\tstd::lock_guard&lt;uMutex&gt; lock{mMutex};\r\n\t\twhile (!mQueue.empty())\r\n\t\t{\r\n\t\t\tmQueue.pop();\r\n\t\t}\r\n\t\tmCondition.notify_all();\r\n\t}\r\n\r\n\t\/\/ Kuyrugu tasarladigimiz yaklasimdan oturu. Kuyrugu yok etmeden once veya uygulamadan cikmadan once\r\n\t\/\/ herhangi bir bekleyen thread var ise burada onlar haberdar ediliyor. Bu cagridan sonra artik\r\n\t\/\/ kuyruk kullan\u0131lmaz hale gelir.\r\n\tvoid invalidate(void)\r\n\t{\r\n\t\tstd::lock_guard&lt;uMutex&gt; lock{ mMutex };\r\n\t\tmValid = false;\r\n\t\tmCondition.notify_all();\r\n\t}\r\n\r\n\t\/\/ Mevcut kuyruk kullan\u0131labilir mi, degil mi?\r\n\tbool isValid(void) const\r\n\t{\r\n\t\tstd::lock_guard&lt;uMutex&gt; lock{ mMutex };\r\n\t\treturn mValid;\r\n\t}\r\n\r\nprivate:\r\n\tstd::atomic_bool        mValid{ true };\r\n\tuMutex                  mMutex;\r\n\tstd::queue&lt;T&gt;           mQueue;\r\n\tstd::condition_variable mCondition;\r\n};<\/pre>\n<p><span style=\"font-weight: 400;\">Bu \u00f6rnek ile asl\u0131nda \u00e7o\u011fu senkronizasyon yap\u0131s\u0131n\u0131n birlikte nas\u0131l kullan\u0131labilece\u011fini de g\u00f6rm\u00fc\u015f olduk. <\/span><\/p>\n<p><span style=\"font-weight: 400;\">Burada bahsetti\u011fim ko\u015fullu de\u011fi\u015fkenleri bir ka\u00e7 API\u2019si daha var ama onlar\u0131n da kullan\u0131m\u0131 ayn\u0131 mant\u0131k, sadece baz\u0131 ek kullan\u0131m kolayl\u0131klar\u0131 (verilen zaman ya da zamana kadar bekle gibi) sunuluyor. Onlara da bakmak i\u00e7in <\/span><strong><span style=\"color: #008000;\"><a style=\"color: #008000;\" href=\"https:\/\/en.cppreference.com\/w\/cpp\/thread\/condition_variable\">https:\/\/en.cppreference.com\/w\/cpp\/thread\/condition_variable<\/a><\/span><\/strong><span style=\"font-weight: 400;\"> sayfas\u0131na bir g\u00f6z atabilirsiniz.<\/span><\/p>\n<h2><strong><span style=\"color: #0000ff;\">Sonu\u00e7:<\/span><\/strong><\/h2>\n<p><span style=\"font-weight: 400;\">Evet arkada\u015flar, \u00fc\u00e7 yaz\u0131l\u0131k thread maceram\u0131z nihayet son buluyor. Bu \u00fc\u00e7 yaz\u0131 ile birlikte C++ thread k\u00fct\u00fcphanesine ili\u015fkin en \u00f6nemli yap\u0131lar\u0131 sizlere aktarmaya \u00e7al\u0131\u015ft\u0131m, umar\u0131m faydal\u0131 olmu\u015ftur. Bundan sonraki ad\u0131m, tabiki bunlar\u0131 kullanmak \ud83d\ude42 Her ne kadar k\u00fct\u00fcphaneye ili\u015fkin anlatacaklar\u0131m bitse de, multithreaded programlamaya ili\u015fkin bir yaz\u0131m daha olacak, sonra yeni yaz\u0131lara yelken a\u00e7abiliriz.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">Ben yaz\u0131l\u0131mperver, bol ve e\u011flenceli kodlamalar \ud83d\ude42<\/span><\/p>\n<h2><strong><span style=\"color: #0000ff;\">Kaynaklar:<\/span><\/strong><\/h2>\n<ul>\n<li><span style=\"color: #008000;\"><strong><a style=\"color: #008000;\" href=\"https:\/\/en.cppreference.com\/w\/cpp\/thread\">https:\/\/en.cppreference.com\/w\/cpp\/thread<\/a><\/strong><\/span><\/li>\n<li><span style=\"color: #008000;\"><strong><a style=\"color: #008000;\" href=\"http:\/\/web.mit.edu\/6.005\/www\/fa15\/classes\/23-locks\/\">http:\/\/web.mit.edu\/6.005\/www\/fa15\/classes\/23-locks\/<\/a><\/strong><\/span><\/li>\n<li><span style=\"color: #008000;\"><strong><a style=\"color: #008000;\" href=\"http:\/\/www.modernescpp.com\/index.php\/c-core-guidelines-be-aware-of-the-traps-of-condition-variables\">http:\/\/www.modernescpp.com\/index.php\/c-core-guidelines-be-aware-of-the-traps-of-condition-variables<\/a><\/strong><\/span><\/li>\n<li><span style=\"color: #008000;\"><strong><a style=\"color: #008000;\" href=\"https:\/\/solarianprogrammer.com\/2011\/12\/16\/cpp-11-thread-tutorial\/\">https:\/\/solarianprogrammer.com\/2011\/12\/16\/cpp-11-thread-tutorial\/<\/a><\/strong><\/span><\/li>\n<li><span style=\"color: #008000;\"><strong><a style=\"color: #008000;\" href=\"https:\/\/thispointer.com\/category\/multithreading\/\">https:\/\/thispointer.com\/category\/multithreading\/<\/a><\/strong><\/span><\/li>\n<li><strong><span style=\"color: #008000;\"><a style=\"color: #008000;\" href=\"https:\/\/stackoverflow.com\/questions\/17113619\/whats-the-best-way-to-lock-multiple-stdmutexes\/17113678\">https:\/\/stackoverflow.com\/questions\/17113619\/whats-the-best-way-to-lock-multiple-stdmutexes\/17113678<\/a><\/span><\/strong><\/li>\n<li><strong><span style=\"color: #008000;\"><a style=\"color: #008000;\" href=\"https:\/\/www.amazon.com\/Modern-Operating-Systems-Andrew-Tanenbaum\/dp\/013359162X\">Tanenbaum\u2019s Modern Operating Systems book<\/a><\/span><\/strong><\/li>\n<li><strong><span style=\"color: #008000;\"><a style=\"color: #008000;\" href=\"https:\/\/www.amazon.com\/C-Concurrency-Action-Anthony-Williams\/dp\/1617294691\/ref=pd_lpo_sbs_14_img_0?_encoding=UTF8&amp;psc=1&amp;refRID=ZXET66SHQDZSWECSTNBQ\">Anthony Williams C++ Concurreny in Action books<\/a>.<\/span><\/strong><\/li>\n<\/ul>\n<p><\/p>","protected":false},"excerpt":{"rendered":"<p>Merhaba arkada\u015flar, uzun bir aradan sonra haftal\u0131k C++ yaz\u0131lar\u0131m\u0131za devam ediyoruz. std::thread k\u00fct\u00fcphanesine ili\u015fkin daha \u00f6nce ba\u015flam\u0131\u015f oldu\u011fumuz serinin \u00fc\u00e7\u00fcnc\u00fc yaz\u0131s\u0131 ile sizler ile birlikteyim. E\u011fer di\u011fer yaz\u0131lar\u0131m\u0131 hen\u00fcz okumad\u0131 iseniz, a\u015fa\u011f\u0131daki ba\u011flant\u0131lardan muhakkak okuman\u0131z \u00f6neriyorum, \u00f6zellikle birinci yaz\u0131y\u0131: Haftal\u0131k C++ 7- std::thread (I) Haftal\u0131k C++ 8- std::thread (II) Haftal\u0131k C++ 10- std::thread (III) Giri\u015f:&#8230; <a class=\"more-link\" href=\"https:\/\/www.yazilimperver.com\/index.php\/2019\/03\/08\/haftalik-c-10-stdthread-iii\/\">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":[320,13,373,374,369,42,292,370,376,375,372,371,291],"class_list":["post-874","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-c","category-modern-c","tag-atomics","tag-c","tag-condition-variables","tag-critical-section","tag-dead-lock","tag-modern-c","tag-multithreaded-programming","tag-mutex","tag-mutual-exclusion","tag-race-condition","tag-stdcondition_variable","tag-stdmutex","tag-thread"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v21.0 - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>Haftal\u0131k C++ 10- std::thread (III) - 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\/03\/08\/haftalik-c-10-stdthread-iii\/\" \/>\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++ 10- std::thread (III)[:en]Weeky C++ 10- std::thread (III)[:] - Yaz\u0131l\u0131mperver&#039;in D\u00fcnyas\u0131\" \/>\n<meta property=\"og:description\" content=\"Merhaba arkada\u015flar, uzun bir aradan sonra haftal\u0131k C++ yaz\u0131lar\u0131m\u0131za devam ediyoruz. std::thread k\u00fct\u00fcphanesine ili\u015fkin daha \u00f6nce ba\u015flam\u0131\u015f oldu\u011fumuz serinin \u00fc\u00e7\u00fcnc\u00fc yaz\u0131s\u0131 ile sizler ile birlikteyim. E\u011fer di\u011fer yaz\u0131lar\u0131m\u0131 hen\u00fcz okumad\u0131 iseniz, a\u015fa\u011f\u0131daki ba\u011flant\u0131lardan muhakkak okuman\u0131z \u00f6neriyorum, \u00f6zellikle birinci yaz\u0131y\u0131: Haftal\u0131k C++ 7- std::thread (I) Haftal\u0131k C++ 8- std::thread (II) Haftal\u0131k C++ 10- std::thread (III) Giri\u015f:... Continue reading &#8594;\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.yazilimperver.com\/index.php\/2019\/03\/08\/haftalik-c-10-stdthread-iii\/\" \/>\n<meta property=\"og:site_name\" content=\"Yaz\u0131l\u0131mperver&#039;in D\u00fcnyas\u0131\" \/>\n<meta property=\"article:published_time\" content=\"2019-03-08T19:43:09+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2019-03-23T20:57:43+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\/03\/08\/haftalik-c-10-stdthread-iii\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/www.yazilimperver.com\/index.php\/2019\/03\/08\/haftalik-c-10-stdthread-iii\/\"},\"author\":{\"name\":\"yaz\u0131l\u0131mperver\",\"@id\":\"https:\/\/www.yazilimperver.com\/#\/schema\/person\/6497f6de4df6ba469748b861a2b3fcdb\"},\"headline\":\"Haftal\u0131k C++ 10- std::thread (III)\",\"datePublished\":\"2019-03-08T19:43:09+00:00\",\"dateModified\":\"2019-03-23T20:57:43+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/www.yazilimperver.com\/index.php\/2019\/03\/08\/haftalik-c-10-stdthread-iii\/\"},\"wordCount\":5278,\"commentCount\":1,\"publisher\":{\"@id\":\"https:\/\/www.yazilimperver.com\/#\/schema\/person\/6497f6de4df6ba469748b861a2b3fcdb\"},\"keywords\":[\"atomics\",\"c++\",\"condition variables\",\"critical section\",\"dead lock\",\"Modern C++\",\"multithreaded programming\",\"mutex\",\"mutual exclusion\",\"race condition\",\"std::condition_variable\",\"std::mutex\",\"thread\"],\"articleSection\":[\"C++\",\"Modern C++\"],\"inLanguage\":\"tr\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\/\/www.yazilimperver.com\/index.php\/2019\/03\/08\/haftalik-c-10-stdthread-iii\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/www.yazilimperver.com\/index.php\/2019\/03\/08\/haftalik-c-10-stdthread-iii\/\",\"url\":\"https:\/\/www.yazilimperver.com\/index.php\/2019\/03\/08\/haftalik-c-10-stdthread-iii\/\",\"name\":\"[:tr]Haftal\u0131k C++ 10- std::thread (III)[:en]Weeky C++ 10- std::thread (III)[:] - Yaz\u0131l\u0131mperver&#039;in D\u00fcnyas\u0131\",\"isPartOf\":{\"@id\":\"https:\/\/www.yazilimperver.com\/#website\"},\"datePublished\":\"2019-03-08T19:43:09+00:00\",\"dateModified\":\"2019-03-23T20:57:43+00:00\",\"breadcrumb\":{\"@id\":\"https:\/\/www.yazilimperver.com\/index.php\/2019\/03\/08\/haftalik-c-10-stdthread-iii\/#breadcrumb\"},\"inLanguage\":\"tr\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/www.yazilimperver.com\/index.php\/2019\/03\/08\/haftalik-c-10-stdthread-iii\/\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/www.yazilimperver.com\/index.php\/2019\/03\/08\/haftalik-c-10-stdthread-iii\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Ana sayfa\",\"item\":\"https:\/\/www.yazilimperver.com\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Haftal\u0131k C++ 10- std::thread (III)\"}]},{\"@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++ 10- std::thread (III)[:en]Weeky C++ 10- std::thread (III)[:] - 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\/03\/08\/haftalik-c-10-stdthread-iii\/","og_locale":"tr_TR","og_type":"article","og_title":"[:tr]Haftal\u0131k C++ 10- std::thread (III)[:en]Weeky C++ 10- std::thread (III)[:] - Yaz\u0131l\u0131mperver&#039;in D\u00fcnyas\u0131","og_description":"Merhaba arkada\u015flar, uzun bir aradan sonra haftal\u0131k C++ yaz\u0131lar\u0131m\u0131za devam ediyoruz. std::thread k\u00fct\u00fcphanesine ili\u015fkin daha \u00f6nce ba\u015flam\u0131\u015f oldu\u011fumuz serinin \u00fc\u00e7\u00fcnc\u00fc yaz\u0131s\u0131 ile sizler ile birlikteyim. E\u011fer di\u011fer yaz\u0131lar\u0131m\u0131 hen\u00fcz okumad\u0131 iseniz, a\u015fa\u011f\u0131daki ba\u011flant\u0131lardan muhakkak okuman\u0131z \u00f6neriyorum, \u00f6zellikle birinci yaz\u0131y\u0131: Haftal\u0131k C++ 7- std::thread (I) Haftal\u0131k C++ 8- std::thread (II) Haftal\u0131k C++ 10- std::thread (III) Giri\u015f:... Continue reading &#8594;","og_url":"https:\/\/www.yazilimperver.com\/index.php\/2019\/03\/08\/haftalik-c-10-stdthread-iii\/","og_site_name":"Yaz\u0131l\u0131mperver&#039;in D\u00fcnyas\u0131","article_published_time":"2019-03-08T19:43:09+00:00","article_modified_time":"2019-03-23T20:57:43+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\/03\/08\/haftalik-c-10-stdthread-iii\/#article","isPartOf":{"@id":"https:\/\/www.yazilimperver.com\/index.php\/2019\/03\/08\/haftalik-c-10-stdthread-iii\/"},"author":{"name":"yaz\u0131l\u0131mperver","@id":"https:\/\/www.yazilimperver.com\/#\/schema\/person\/6497f6de4df6ba469748b861a2b3fcdb"},"headline":"Haftal\u0131k C++ 10- std::thread (III)","datePublished":"2019-03-08T19:43:09+00:00","dateModified":"2019-03-23T20:57:43+00:00","mainEntityOfPage":{"@id":"https:\/\/www.yazilimperver.com\/index.php\/2019\/03\/08\/haftalik-c-10-stdthread-iii\/"},"wordCount":5278,"commentCount":1,"publisher":{"@id":"https:\/\/www.yazilimperver.com\/#\/schema\/person\/6497f6de4df6ba469748b861a2b3fcdb"},"keywords":["atomics","c++","condition variables","critical section","dead lock","Modern C++","multithreaded programming","mutex","mutual exclusion","race condition","std::condition_variable","std::mutex","thread"],"articleSection":["C++","Modern C++"],"inLanguage":"tr","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/www.yazilimperver.com\/index.php\/2019\/03\/08\/haftalik-c-10-stdthread-iii\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/www.yazilimperver.com\/index.php\/2019\/03\/08\/haftalik-c-10-stdthread-iii\/","url":"https:\/\/www.yazilimperver.com\/index.php\/2019\/03\/08\/haftalik-c-10-stdthread-iii\/","name":"[:tr]Haftal\u0131k C++ 10- std::thread (III)[:en]Weeky C++ 10- std::thread (III)[:] - Yaz\u0131l\u0131mperver&#039;in D\u00fcnyas\u0131","isPartOf":{"@id":"https:\/\/www.yazilimperver.com\/#website"},"datePublished":"2019-03-08T19:43:09+00:00","dateModified":"2019-03-23T20:57:43+00:00","breadcrumb":{"@id":"https:\/\/www.yazilimperver.com\/index.php\/2019\/03\/08\/haftalik-c-10-stdthread-iii\/#breadcrumb"},"inLanguage":"tr","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.yazilimperver.com\/index.php\/2019\/03\/08\/haftalik-c-10-stdthread-iii\/"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/www.yazilimperver.com\/index.php\/2019\/03\/08\/haftalik-c-10-stdthread-iii\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Ana sayfa","item":"https:\/\/www.yazilimperver.com\/"},{"@type":"ListItem","position":2,"name":"Haftal\u0131k C++ 10- std::thread (III)"}]},{"@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\/874","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=874"}],"version-history":[{"count":12,"href":"https:\/\/www.yazilimperver.com\/index.php\/wp-json\/wp\/v2\/posts\/874\/revisions"}],"predecessor-version":[{"id":1072,"href":"https:\/\/www.yazilimperver.com\/index.php\/wp-json\/wp\/v2\/posts\/874\/revisions\/1072"}],"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=874"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.yazilimperver.com\/index.php\/wp-json\/wp\/v2\/categories?post=874"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.yazilimperver.com\/index.php\/wp-json\/wp\/v2\/tags?post=874"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}