{"id":31458,"date":"2025-10-10T05:31:42","date_gmt":"2025-10-10T02:31:42","guid":{"rendered":"https:\/\/fatihsoysal.com\/blog\/go-ile-eszamanlilik-kontrolu-semapfor-deseni-nasil-kullanilir\/"},"modified":"2025-10-10T05:31:42","modified_gmt":"2025-10-10T02:31:42","slug":"go-ile-eszamanlilik-kontrolu-semapfor-deseni-nasil-kullanilir","status":"publish","type":"post","link":"https:\/\/fatihsoysal.com\/blog\/go-ile-eszamanlilik-kontrolu-semapfor-deseni-nasil-kullanilir\/","title":{"rendered":"Go ile E\u015fzamanl\u0131l\u0131k Kontrol\u00fc: Semapfor Deseni Nas\u0131l Kullan\u0131l\u0131r?"},"content":{"rendered":"<p>Go programlamada e\u015fzamanl\u0131 kaynak y\u00f6netimi sizi zorluyor mu? Semapfor deseni ile <code>goroutine<\/code>&#8216;lerinizi etkili bir \u015fekilde senkronize ederek veri yar\u0131\u015flar\u0131n\u0131 \u00f6nleyebilir ve sisteminizin kararl\u0131l\u0131\u011f\u0131n\u0131 art\u0131rabilirsiniz. Bu rehberde, Go&#8217;da semapforun ne oldu\u011funu, neden \u00f6nemli oldu\u011funu ve pratik \u00f6rneklerle nas\u0131l uygulanaca\u011f\u0131n\u0131 ad\u0131m ad\u0131m ke\u015ffedece\u011fiz. Gelin, Go&#8217;nun g\u00fc\u00e7l\u00fc e\u015fzamanl\u0131l\u0131k \u00f6zelliklerini semapfor deseniyle nas\u0131l daha verimli kullanabilece\u011finizi birlikte \u00f6\u011frenelim.<\/p>\n<p>Go, e\u015fzamanl\u0131 programlama i\u00e7in tasarlanm\u0131\u015f modern bir dildir ve <code>goroutine<\/code>&#8216;ler ile kanallar (<code>channels<\/code>) sayesinde paralel i\u015flemleri inan\u0131lmaz derecede kolayla\u015ft\u0131r\u0131r. Ancak bu g\u00fc\u00e7, beraberinde belirli zorluklar\u0131 da getirir. \u00d6zellikle, birden fazla <code>goroutine<\/code>&#8216;in ayn\u0131 anda payla\u015f\u0131lan kaynaklara eri\u015fmeye \u00e7al\u0131\u015ft\u0131\u011f\u0131 durumlarda, veri yar\u0131\u015flar\u0131 (data races), kilitlenmeler (deadlocks) ve kaynak t\u00fckenmesi gibi problemlerle kar\u015f\u0131la\u015fmak olas\u0131d\u0131r. \u00d6rne\u011fin, bir web sunucusu d\u00fc\u015f\u00fcn\u00fcn; y\u00fczlerce, hatta binlerce e\u015fzamanl\u0131 iste\u011fi i\u015flerken, her bir iste\u011fin bir veritaban\u0131 ba\u011flant\u0131s\u0131 veya harici bir API hizmeti gibi s\u0131n\u0131rl\u0131 kaynaklara kontroll\u00fc bir \u015fekilde eri\u015fmesi gerekir. E\u011fer bu eri\u015fim do\u011fru y\u00f6netilmezse, sunucu performans\u0131 d\u00fc\u015febilir, hatalar meydana gelebilir ve hatta t\u00fcm sistem \u00e7\u00f6kebilir.<\/p>\n<p><code>Goroutine<\/code>&#8216;ler hafif olmalar\u0131 ve kolayca olu\u015fturulabilmeleri nedeniyle Go geli\u015ftiricileri aras\u0131nda \u00e7ok pop\u00fclerdir. Ancak, bir uygulaman\u0131n binlerce <code>goroutine<\/code>&#8216;i ayn\u0131 anda \u00e7al\u0131\u015ft\u0131rmas\u0131, sistemin kapasitesini a\u015fabilecek potansiyel bir risk ta\u015f\u0131r. Her bir <code>goroutine<\/code>&#8216;in bellek t\u00fcketimi nispeten d\u00fc\u015f\u00fck olsa da, toplamda \u00f6nemli bir kaynak y\u00fck\u00fc olu\u015fturabilir. Dahas\u0131, a\u015f\u0131r\u0131 say\u0131da e\u015fzamanl\u0131 i\u015flem, i\u015fletim sisteminin ba\u011flam de\u011fi\u015ftirme (context switching) y\u00fck\u00fcn\u00fc art\u0131rarak genel performans\u0131 olumsuz etkileyebilir. Bu noktada, sistem kaynaklar\u0131n\u0131 verimli bir \u015fekilde kullanabilmek ve uygulaman\u0131n kararl\u0131l\u0131\u011f\u0131n\u0131 sa\u011flamak i\u00e7in belirli bir e\u015fzamanl\u0131l\u0131k kontrol mekanizmas\u0131na ihtiya\u00e7 duyar\u0131z. \u0130\u015fte bu noktada semapfor deseni devreye girer. Semapfor, e\u015fzamanl\u0131 olarak belirli bir kayna\u011fa eri\u015febilecek <code>goroutine<\/code> say\u0131s\u0131n\u0131 s\u0131n\u0131rlayarak, bu t\u00fcr problemlerin \u00f6n\u00fcne ge\u00e7memizi sa\u011flar. Bu sayede, hem kaynaklar\u0131m\u0131z\u0131 etkin kullanm\u0131\u015f oluruz hem de uygulamam\u0131z\u0131n beklenmeyen davran\u0131\u015flar sergilemesinin \u00f6n\u00fcne ge\u00e7eriz. K\u0131sacas\u0131, Go&#8217;da e\u015fzamanl\u0131l\u0131k b\u00fcy\u00fck bir avantaj sunarken, bu avantaj\u0131 ak\u0131ll\u0131ca y\u00f6netmek, g\u00fc\u00e7l\u00fc ve dayan\u0131kl\u0131 uygulamalar geli\u015ftirmek i\u00e7in kritik \u00f6neme sahiptir.<\/p>\n<p>Ayn\u0131 zamanda, karma\u015f\u0131k sistemlerde birden fazla e\u015fzamanl\u0131 g\u00f6revin birbiriyle etkile\u015fimi, hatalar\u0131n tespitini ve d\u00fczeltilmesini zorla\u015ft\u0131rabilir. \u00d6rne\u011fin, bir i\u015flem belirli bir kayna\u011f\u0131 tutarken ba\u015fka bir i\u015flemin o kayna\u011f\u0131 sonsuza dek beklemesi kilitlenmelere yol a\u00e7abilir. Veya, birden fazla <code>goroutine<\/code>&#8216;in bir payla\u015f\u0131lan veri yap\u0131s\u0131n\u0131 korumas\u0131z bir \u015fekilde de\u011fi\u015ftirmesi, \u00f6ng\u00f6r\u00fclemeyen sonu\u00e7lar do\u011furan veri bozulmalar\u0131na neden olabilir. Bu t\u00fcr durumlar, \u00f6zellikle y\u00fcksek trafikli uygulamalarda ciddi g\u00fcvenlik ve kararl\u0131l\u0131k sorunlar\u0131na yol a\u00e7abilir. Bu nedenle, Go gibi e\u015fzamanl\u0131l\u0131\u011f\u0131 temel alan bir dilde, geli\u015ftiricilerin bu potansiyel sorunlara kar\u015f\u0131 bilin\u00e7li olmas\u0131 ve uygun e\u015fzamanl\u0131l\u0131k desenlerini kullanarak robust sistemler in\u015fa etmesi elzemdir. Semapfor, bu zorluklar\u0131n \u00fcstesinden gelmek i\u00e7in kullanabilece\u011fimiz temel ancak g\u00fc\u00e7l\u00fc ara\u00e7lardan biridir.<\/p>\n<h2>Semapfor Deseni Nedir ve Neden \u00d6nemlidir?<\/h2>\n<p>Semapfor, bilgisayar bilimlerinde e\u015fzamanl\u0131 programlama alan\u0131nda kullan\u0131lan temel bir senkronizasyon mekanizmas\u0131d\u0131r. Basit\u00e7e ifade etmek gerekirse, semapfor, belirli bir payla\u015f\u0131lan kayna\u011fa ayn\u0131 anda eri\u015febilecek i\u015flem veya <code>goroutine<\/code> say\u0131s\u0131n\u0131 s\u0131n\u0131rlayan bir saya\u00e7 g\u00f6revi g\u00f6r\u00fcr. Bu saya\u00e7, genellikle &#8220;kapasite&#8221; veya &#8220;izin&#8221; olarak adland\u0131r\u0131lan \u00f6nceden tan\u0131mlanm\u0131\u015f bir maksimum de\u011fere sahiptir. Bir <code>goroutine<\/code> bir kayna\u011fa eri\u015fmek istedi\u011finde, semapfordan bir izin ister (<code>acquire<\/code> veya <code>wait<\/code> i\u015flemi). E\u011fer izinler t\u00fckenmediyse, <code>goroutine<\/code> izni al\u0131r ve i\u015flemine devam eder; saya\u00e7 bir azal\u0131r. E\u011fer t\u00fcm izinler kullan\u0131mdaysa, <code>goroutine<\/code> yeni bir izin serbest b\u0131rak\u0131lana kadar bloklan\u0131r ve beklemeye al\u0131n\u0131r. \u0130\u015flemi tamamland\u0131\u011f\u0131nda ise, <code>goroutine<\/code> izni serbest b\u0131rak\u0131r (<code>release<\/code> veya <code>signal<\/code> i\u015flemi) ve saya\u00e7 bir artar, b\u00f6ylece ba\u015fka bir <code>goroutine<\/code>&#8216;in kayna\u011fa eri\u015fmesine izin verilir.<\/p>\n<p>Peki, semapfor deseni Go&#8217;da neden bu kadar \u00f6nemlidir? Go&#8217;da <code>goroutine<\/code>&#8216;ler \u00e7ok hafiftir ve y\u00fczbinlerce <code>goroutine<\/code> ayn\u0131 anda \u00e7al\u0131\u015ft\u0131r\u0131labilir. Ancak, bu <code>goroutine<\/code>&#8216;lerin her biri s\u0131n\u0131rl\u0131 kaynaklara (\u00f6rne\u011fin, bir veritaban\u0131 ba\u011flant\u0131 havuzu, harici bir API&#8217;ye e\u015fzamanl\u0131 istek limiti, dosya kilitleme veya bellekte belirli bir b\u00f6lge) eri\u015fmeye \u00e7al\u0131\u015ft\u0131\u011f\u0131nda, bu kaynaklar\u0131n a\u015f\u0131r\u0131 y\u00fcklenmesi veya t\u00fckenmesi riski ortaya \u00e7\u0131kar. Semapforlar, bu t\u00fcr senaryolarda kritik bir rol oynar. Onlar sayesinde, bir kayna\u011f\u0131n e\u015fzamanl\u0131 kullan\u0131m\u0131n\u0131 kontrol alt\u0131nda tutabilir, sistemin a\u015f\u0131r\u0131 y\u00fcklenmesini \u00f6nleyebilir ve b\u00f6ylece uygulaman\u0131n istikrar\u0131n\u0131 ve performans\u0131n\u0131 art\u0131rabiliriz. \u00d6rne\u011fin, bir web uygulamas\u0131n\u0131n ayn\u0131 anda sadece 100 veritaban\u0131 ba\u011flant\u0131s\u0131 a\u00e7mas\u0131na izin vermek isteyebilirsiniz. Semapfor kullanarak, 101. ba\u011flant\u0131 iste\u011fi geldi\u011finde, mevcut ba\u011flant\u0131lardan biri serbest kalana kadar bu iste\u011fi bekletebilirsiniz. Bu, veritaban\u0131 sunucusunun a\u015f\u0131r\u0131 y\u00fcklenmesini engeller ve uygulama genelinde daha d\u00fczenli bir kaynak kullan\u0131m\u0131n\u0131 te\u015fvik eder.<\/p>\n<p>Semapforlar ayr\u0131ca, karma\u015f\u0131k e\u015fzamanl\u0131 mant\u0131kta ortaya \u00e7\u0131kabilecek veri yar\u0131\u015flar\u0131n\u0131 ve kilitlenmeleri \u00f6nlemeye yard\u0131mc\u0131 olur. Bir kayna\u011fa eri\u015fimin kontrol alt\u0131nda tutulmas\u0131, birden fazla <code>goroutine<\/code>&#8216;in ayn\u0131 veriyi ayn\u0131 anda de\u011fi\u015ftirmesini engeller, b\u00f6ylece veri tutarl\u0131l\u0131\u011f\u0131 sa\u011flan\u0131r. Ayr\u0131ca, belirli bir i\u015flem s\u0131ras\u0131n\u0131 veya kaynak eri\u015fim \u00f6nceli\u011fini uygulaman\u0131n bir yolu olarak da kullan\u0131labilirler. \u00d6rne\u011fin, bir g\u00f6rev kuyru\u011funda, ayn\u0131 anda i\u015flenecek g\u00f6rev say\u0131s\u0131n\u0131 semapfor ile s\u0131n\u0131rlayarak, i\u015fleyicilerin sistemin kald\u0131rabilece\u011finden fazla i\u015fi \u00fcstlenmesini \u00f6nleyebiliriz. Bu, \u00f6zellikle kaynak yo\u011fun g\u00f6revlerde veya harici hizmetlerle etkile\u015fimde bulunan uygulamalarda hayati \u00f6neme sahiptir. Sonu\u00e7 olarak, semapfor deseni Go&#8217;da e\u015fzamanl\u0131l\u0131k y\u00f6netiminde vazge\u00e7ilmez bir ara\u00e7t\u0131r; sistemlerinizi daha g\u00fcvenli, daha kararl\u0131 ve daha performansl\u0131 hale getirmenin anahtarlar\u0131ndan birini sunar. Uygulaman\u0131z\u0131n karma\u015f\u0131kl\u0131\u011f\u0131 artt\u0131k\u00e7a, bu t\u00fcr senkronizasyon mekanizmalar\u0131na olan ihtiya\u00e7 da artacakt\u0131r, bu y\u00fczden semapforlar\u0131 anlamak ve do\u011fru bir \u015fekilde kullanmak, her Go geli\u015ftiricisinin ara\u00e7 setinde bulunmas\u0131 gereken bir beceridir.<\/p>\n<h2>Go&#8217;da Basit Bir Semapfor Nas\u0131l Olu\u015fturulur ve Kullan\u0131l\u0131r?<\/h2>\n<p>Go&#8217;da semapfor deseni uygulamak i\u00e7in genellikle iki yayg\u0131n yakla\u015f\u0131m vard\u0131r: Go&#8217;nun kendi <code>channel<\/code>&#8216;lar\u0131n\u0131 kullanarak \u00f6zel bir semapfor olu\u015fturmak veya <code>golang.org\/x\/sync\/semaphore<\/code> paketini kullanmak. Bu b\u00f6l\u00fcmde, ilk olarak Go&#8217;nun yerle\u015fik kanallar\u0131n\u0131 kullanarak nas\u0131l basit bir semapfor olu\u015fturaca\u011f\u0131m\u0131z\u0131 ad\u0131m ad\u0131m inceleyece\u011fiz, zira bu yakla\u015f\u0131m Go&#8217;nun e\u015fzamanl\u0131l\u0131k felsefesini daha iyi yans\u0131t\u0131r. Daha sonra, <code>x\/sync\/semaphore<\/code> paketine de k\u0131saca de\u011finece\u011fiz.<\/p>\n<h3>Kanallar ile \u00d6zel Bir Semapfor Olu\u015fturma<\/h3>\n<p>Go&#8217;da bir kanal (<code>channel<\/code>), e\u015fzamanl\u0131 <code>goroutine<\/code>&#8216;ler aras\u0131nda ileti\u015fim kurman\u0131n temel yoludur. Tamponlanm\u0131\u015f (buffered) bir kanal, semapfor i\u015flevi g\u00f6rmek i\u00e7in m\u00fckemmel bir ara\u00e7t\u0131r. Kanal\u0131n kapasitesi, e\u015fzamanl\u0131 olarak izin verilen i\u015flem say\u0131s\u0131n\u0131 belirler. Bir <code>goroutine<\/code> izni almak i\u00e7in kanala bir de\u011fer g\u00f6nderir (<code>send<\/code> i\u015flemi), izni serbest b\u0131rakmak i\u00e7in kanaldan bir de\u011fer al\u0131r (<code>receive<\/code> i\u015flemi).<\/p>\n<h4>Ad\u0131m 1: Semapfor Yap\u0131s\u0131n\u0131 Tan\u0131mlama<\/h4>\n<p>\u0130lk olarak, semapforumuzu temsil edecek bir yap\u0131 tan\u0131mlayal\u0131m. Bu yap\u0131, tamponlanm\u0131\u015f bir kanal i\u00e7erecektir.<\/p>\n<pre><code class=\"language-go\">\npackage main\n\nimport (\n    \"fmt\"\n    \"sync\"\n    \"time\"\n)\n\n\/\/ Semaphore, e\u015fzamanl\u0131 eri\u015fimi kontrol etmek i\u00e7in bir yap\u0131 tan\u0131mlar.\ntype Semaphore chan struct{}\n\n\/\/ NewSemaphore, belirli bir kapasiteye sahip yeni bir semapfor olu\u015fturur.\nfunc NewSemaphore(capacity int) Semaphore {\n    return make(chan struct{}, capacity)\n}\n<\/pre>\n<p><\/code><\/p>\n<p>Burada, <code>Semaphore<\/code> tipini <code>chan struct{}<\/code> olarak tan\u0131mlad\u0131k. <code>struct{}<\/code> bo\u015f bir yap\u0131 oldu\u011fu i\u00e7in, kanala g\u00f6nderilen ve kanaldan al\u0131nan de\u011ferler minimum bellek t\u00fcketir; \u00f6nemli olan sadece kanal\u0131n tampon boyutunu kullanmakt\u0131r.<\/p>\n<h4>Ad\u0131m 2: \u0130zin Alma (Acquire) ve Serbest B\u0131rakma (Release) Fonksiyonlar\u0131<\/h4>\n<p>\u015eimdi, <code>goroutine<\/code>'lerin semapfordan izin almas\u0131n\u0131 ve izinleri serbest b\u0131rakmas\u0131n\u0131 sa\u011flayacak metotlar\u0131 ekleyelim:<\/p>\n<pre><code class=\"language-go\">\n\/\/ Acquire, semapfordan bir izin al\u0131r. \u0130zin yoksa bloklan\u0131r.\nfunc (s Semaphore) Acquire() {\n    s <- struct{}{} \/\/ Kanala bir de\u011fer g\u00f6ndererek izin al\n}\n\n\/\/ Release, semafora bir izin geri verir.\nfunc (s Semaphore) Release() {\n    <-s \/\/ Kanaldan bir de\u011fer alarak izni serbest b\u0131rak\n}\n<\/pre>\n<p><\/code><\/p>\n<p><code>Acquire<\/code> metodu, kanala bir bo\u015f yap\u0131 g\u00f6nderir. E\u011fer kanal\u0131n tamponu doluysa (yani t\u00fcm izinler kullan\u0131l\u0131yorsa), bu i\u015flem bloklan\u0131r. <code>Release<\/code> metodu ise kanaldan bir bo\u015f yap\u0131 alarak bir izni serbest b\u0131rak\u0131r ve bekleyen bir <code>goroutine<\/code> varsa blokaj\u0131n\u0131 kald\u0131r\u0131r.<\/p>\n<h4>Ad\u0131m 3: Semapforu Uygulama \u00d6rne\u011fi<\/h4>\n<p>\u015eimdi bu semapforu kullanarak, e\u015fzamanl\u0131 olarak sadece belirli say\u0131da i\u015flemin y\u00fcr\u00fct\u00fclmesine izin veren bir \u00f6rnek olu\u015ftural\u0131m. \u00d6rne\u011fin, ayn\u0131 anda sadece 3 i\u015fin \u00e7al\u0131\u015fmas\u0131na izin verelim.<\/p>\n<pre><code class=\"language-go\">\nfunc main() {\n    const maxConcurrent = 3 \/\/ Ayn\u0131 anda \u00e7al\u0131\u015facak maksimum goroutine say\u0131s\u0131\n    sem := NewSemaphore(maxConcurrent)\n    var wg sync.WaitGroup \/\/ T\u00fcm goroutine'lerin bitmesini beklemek i\u00e7in\n\n    fmt.Println(\"Semapfor ile e\u015fzamanl\u0131 g\u00f6rev y\u00f6netimi ba\u015fl\u0131yor.\")\n\n    for i := 0; i < 10; i++ {\n        wg.Add(1)\n        go func(id int) {\n            defer wg.Done()\n\n            sem.Acquire() \/\/ Bir izin al\n            defer sem.Release() \/\/ \u0130\u015flem bitti\u011finde izni serbest b\u0131rak\n\n            fmt.Printf(\"G\u00f6rev %d ba\u015flad\u0131...\\n\", id)\n            time.Sleep(time.Duration(2+id%3) * time.Second) \/\/ Rastgele bir s\u00fcre uyukla\n            fmt.Printf(\"G\u00f6rev %d bitti.\\n\", id)\n\n        }(i)\n    }\n\n    wg.Wait() \/\/ T\u00fcm g\u00f6revlerin bitmesini bekle\n    fmt.Println(\"T\u00fcm g\u00f6revler tamamland\u0131.\")\n}\n<\/pre>\n<p><\/code><\/p>\n<p>Bu \u00f6rnekte, <code>maxConcurrent<\/code> de\u011ferine sahip bir semapfor olu\u015fturduk. 10 farkl\u0131 <code>goroutine<\/code> ba\u015flat\u0131yoruz, ancak ayn\u0131 anda sadece 3 tanesi aktif olarak \u00e7al\u0131\u015fabilecek. Her <code>goroutine<\/code>, ba\u015flamadan \u00f6nce <code>sem.Acquire()<\/code> \u00e7a\u011f\u0131rarak bir izin al\u0131r ve i\u015fi bitti\u011finde <code>defer sem.Release()<\/code> ile izni serbest b\u0131rak\u0131r. <code>sync.WaitGroup<\/code> ise ana <code>goroutine<\/code>'in t\u00fcm alt <code>goroutine<\/code>'lerin tamamlanmas\u0131n\u0131 beklemesini sa\u011flar.<\/p>\n<div class=\"expert-tip\">\n  Uzman \u0130pucu: <code>chan struct{}<\/code> kullanmak, kanallar \u00fczerinden mesaj iletirken bellek tahsisini minimumda tutar, \u00e7\u00fcnk\u00fc <code>struct{}<\/code> s\u0131f\u0131r boyutlu bir tiptir. Semapfor gibi sadece sinyalizasyon i\u00e7in kullan\u0131lan durumlarda idealdir.\n<\/div>\n<h3><code>golang.org\/x\/sync\/semaphore<\/code> Paketi ile Semapfor Kullan\u0131m\u0131<\/h3>\n<p>Go ekosistemi, s\u0131k\u00e7a kullan\u0131lan senkronizasyon ihtiya\u00e7lar\u0131 i\u00e7in \u00e7e\u015fitli yard\u0131mc\u0131 ara\u00e7lar sunar. <code>golang.org\/x\/sync\/semaphore<\/code> paketi, \u00f6zellikle daha karma\u015f\u0131k semapfor senaryolar\u0131 i\u00e7in tasarlanm\u0131\u015f resmi bir \u00e7\u00f6z\u00fcmd\u00fcr. Bu paket, daha fazla esneklik ve g\u00fcvenlik sunar, \u00f6rne\u011fin, belirli bir ba\u011flam (<code>context<\/code>) ile izin almay\u0131 deneyebilir ve zaman a\u015f\u0131m\u0131 ekleyebilirsiniz. Bu, \u00f6zellikle iptal edilebilir i\u015flemler i\u00e7in \u00f6nemlidir.<\/p>\n<pre><code class=\"language-go\">\npackage main\n\nimport (\n    \"context\"\n    \"fmt\"\n    \"log\"\n    \"runtime\"\n    \"sync\"\n    \"time\"\n\n    \"golang.org\/x\/sync\/semaphore\"\n)\n\nfunc main() {\n    const maxWeight = 3 \/\/ Toplam izin a\u011f\u0131rl\u0131\u011f\u0131\n    const taskWeight = 1 \/\/ Her g\u00f6revin t\u00fcketti\u011fi a\u011f\u0131rl\u0131k\n\n    \/\/ semaphore.NewWeighted ile bir a\u011f\u0131rl\u0131kl\u0131 semapfor olu\u015fturulur.\n    \/\/ Kapasiteye (maxWeight) kadar a\u011f\u0131rl\u0131k tutabilir.\n    sem := semaphore.NewWeighted(maxWeight)\n    var wg sync.WaitGroup\n\n    fmt.Println(\"x\/sync\/semaphore ile e\u015fzamanl\u0131 g\u00f6rev y\u00f6netimi ba\u015fl\u0131yor.\")\n\n    for i := 0; i < 10; i++ {\n        wg.Add(1)\n        go func(id int) {\n            defer wg.Done()\n            ctx := context.Background() \/\/ Basit bir context\n\n            \/\/ semaphore.Acquire, belirtilen a\u011f\u0131rl\u0131k kadar izin ister.\n            if err := sem.Acquire(ctx, taskWeight); err != nil {\n                log.Printf(\"G\u00f6rev %d izin alamad\u0131: %v\\n\", id, err)\n                return\n            }\n            defer sem.Release(taskWeight) \/\/ \u0130\u015flem bitti\u011finde izni serbest b\u0131rak\n\n            fmt.Printf(\"G\u00f6rev %d ba\u015flad\u0131... (Aktif Goroutine Say\u0131s\u0131: %d)\\n\", id, runtime.NumGoroutine())\n            time.Sleep(time.Duration(2+id%3) * time.Second)\n            fmt.Printf(\"G\u00f6rev %d bitti.\\n\", id)\n        }(i)\n    }\n\n    wg.Wait()\n    fmt.Println(\"T\u00fcm g\u00f6revler tamamland\u0131 (x\/sync\/semaphore).\")\n}\n<\/pre>\n<p><\/code><\/p>\n<p><code>x\/sync\/semaphore<\/code> paketi, \u00f6zellikle a\u011f\u0131rl\u0131kl\u0131 semapforlar i\u00e7in faydal\u0131d\u0131r, burada her g\u00f6revin farkl\u0131 bir \"a\u011f\u0131rl\u0131\u011f\u0131\" veya \"boyutu\" olabilir ve semapforun toplam kapasitesi bu a\u011f\u0131rl\u0131klar \u00fczerinden y\u00f6netilir. \u00d6rne\u011fin, bir veritaban\u0131 ba\u011flant\u0131s\u0131 1 a\u011f\u0131rl\u0131k iken, daha fazla bellek gerektiren bir dosya i\u015flemi 5 a\u011f\u0131rl\u0131k olabilir. Bu paket, Go'nun standart k\u00fct\u00fcphanesinin bir uzant\u0131s\u0131 olup, daha geli\u015fmi\u015f e\u015fzamanl\u0131l\u0131k kontrol\u00fc senaryolar\u0131nda tercih edilmelidir. Her iki yakla\u015f\u0131m da Go'da semapfor uygulaman\u0131z\u0131 sa\u011flar; se\u00e7iminiz projenizin \u00f6zel gereksinimlerine ve karma\u015f\u0131kl\u0131\u011f\u0131na ba\u011fl\u0131d\u0131r.<\/p>\n<h2>Ger\u00e7ek D\u00fcnya Senaryosu: E\u015fzamanl\u0131 API \u0130steklerini Nas\u0131l Limitleyebiliriz?<\/h2>\n<p>Modern uygulamalar genellikle harici API'lerle etkile\u015fime girer. Bu API'lerin \u00e7o\u011fu, sunucular\u0131n\u0131n a\u015f\u0131r\u0131 y\u00fcklenmesini \u00f6nlemek amac\u0131yla e\u015fzamanl\u0131 istek say\u0131s\u0131na veya belirli bir zaman dilimindeki istek h\u0131z\u0131na (rate limit) s\u0131n\u0131rlamalar getirir. Bu t\u00fcr s\u0131n\u0131rlamalara uyulmamas\u0131, API sa\u011flay\u0131c\u0131s\u0131 taraf\u0131ndan isteklerinizin reddedilmesine, uygulaman\u0131z\u0131n ge\u00e7ici olarak engellenmesine veya hatta kal\u0131c\u0131 olarak kara listeye al\u0131nmas\u0131na neden olabilir. \u0130\u015fte bu noktada, Go'da semapfor deseni kullanarak e\u015fzamanl\u0131 API isteklerini etkili bir \u015fekilde limitleyebiliriz. Bu, uygulaman\u0131z\u0131n hem API sa\u011flay\u0131c\u0131s\u0131n\u0131n kurallar\u0131na uymas\u0131n\u0131 sa\u011flar hem de kendi sistem kaynaklar\u0131n\u0131z\u0131n verimli kullan\u0131lmas\u0131n\u0131 garanti eder.<\/p>\n<h3>Vaka Analizi: \u00dc\u00e7\u00fcnc\u00fc Parti API'ye E\u015fzamanl\u0131 \u00c7a\u011fr\u0131lar\u0131 Y\u00f6netme<\/h3>\n<p>Hayal edin ki bir e-ticaret uygulaman\u0131z var ve bu uygulama, \u00fcr\u00fcn fiyatlar\u0131n\u0131 veya stok durumunu g\u00fcncellemek i\u00e7in harici bir tedarik\u00e7i API'sine s\u0131k\u00e7a ba\u015fvuruyor. Bu API, ayn\u0131 anda en fazla 10 paralel iste\u011fe izin veriyor. E\u011fer bu limiti a\u015farsan\u0131z, API size <code>429 Too Many Requests<\/code> hatas\u0131 d\u00f6necektir. Semapfor kullanarak, Go uygulaman\u0131z\u0131n bu kurala uymas\u0131n\u0131 nas\u0131l sa\u011flayabiliriz?<\/p>\n<h4>Ad\u0131m 1: Semapfor ve \u0130stek \u0130\u015fleyicisini Haz\u0131rlama<\/h4>\n<p>\u00d6ncelikle, belirli bir kapasiteye sahip bir semapfor tan\u0131mlamam\u0131z gerekiyor. Bu kapasite, API'nin izin verdi\u011fi maksimum e\u015fzamanl\u0131 istek say\u0131s\u0131na e\u015fit olacakt\u0131r (\u00f6rne\u011fimizde 10).<\/p>\n<pre><code class=\"language-go\">\npackage main\n\nimport (\n    \"fmt\"\n    \"io\/ioutil\"\n    \"net\/http\"\n    \"sync\"\n    \"time\"\n\n    \"golang.org\/x\/sync\/semaphore\" \/\/ x\/sync\/semaphore paketini kullanaca\u011f\u0131z\n    \"context\" \/\/ context paketi gerekli\n)\n\nconst (\n    maxConcurrentRequests = 10 \/\/ API'nin izin verdi\u011fi maksimum e\u015fzamanl\u0131 istek\n    totalRequests         = 50 \/\/ G\u00f6nderilecek toplam istek say\u0131s\u0131\n)\n\nvar (\n    apiSemaphore = semaphore.NewWeighted(maxConcurrentRequests)\n    httpClient   = &http.Client{Timeout: 5 * time.Second} \/\/ HTTP istemcisi tan\u0131ml\u0131yoruz\n)\n\n\/\/ simulateAPIRequest, ger\u00e7ek bir API iste\u011fini sim\u00fcle eder.\nfunc simulateAPIRequest(requestID int) (string, error) {\n    \/\/ API iste\u011fi g\u00f6ndermeden \u00f6nce semapfordan bir izin al\u0131yoruz\n    ctx := context.Background()\n    if err := apiSemaphore.Acquire(ctx, 1); err != nil {\n        return \"\", fmt.Errorf(\"request %d: semapfor izni al\u0131namad\u0131: %w\", requestID, err)\n    }\n    defer apiSemaphore.Release(1) \/\/ \u0130stek tamamland\u0131\u011f\u0131nda izni serbest b\u0131rak\u0131yoruz\n\n    \/\/ Bu k\u0131s\u0131m ger\u00e7ek bir HTTP iste\u011fi olacak\n    url := fmt.Sprintf(\"https:\/\/jsonplaceholder.typicode.com\/posts\/%d\", requestID) \/\/ \u00d6rnek bir API\n    fmt.Printf(\"\u0130stek %d g\u00f6nderiliyor... (Aktif \u0130zinler: %d\/%d)\\n\", requestID, maxConcurrentRequests - apiSemaphore.Available(), maxConcurrentRequests)\n    \n    resp, err := httpClient.Get(url)\n    if err != nil {\n        return \"\", fmt.Errorf(\"request %d ba\u015far\u0131s\u0131z: %w\", requestID, err)\n    }\n    defer resp.Body.Close()\n\n    if resp.StatusCode != http.StatusOK {\n        return \"\", fmt.Errorf(\"request %d: API %s durum kodu d\u00f6nd\u00fcrd\u00fc\", requestID, resp.Status)\n    }\n\n    body, err := ioutil.ReadAll(resp.Body)\n    if err != nil {\n        return \"\", fmt.Errorf(\"request %d: yan\u0131t okunamad\u0131: %w\", requestID, err)\n    }\n\n    return fmt.Sprintf(\"\u0130stek %d ba\u015far\u0131l\u0131. Yan\u0131t boyutu: %d\", requestID, len(body)), nil\n}\n<\/pre>\n<p><\/code><\/p>\n<p>Yukar\u0131daki kodda, <code>apiSemaphore<\/code> ad\u0131nda bir a\u011f\u0131rl\u0131kl\u0131 semapfor olu\u015fturduk. <code>maxConcurrentRequests<\/code> de\u011feri ile ka\u00e7 tane e\u015fzamanl\u0131 iste\u011fe izin verilece\u011fini belirledik. <code>simulateAPIRequest<\/code> fonksiyonumuz, ger\u00e7ek bir API \u00e7a\u011fr\u0131s\u0131 yapmadan \u00f6nce <code>apiSemaphore.Acquire(ctx, 1)<\/code> ile bir izin al\u0131r. E\u011fer mevcut izinler doluysa, bu \u00e7a\u011fr\u0131 bloklan\u0131r ve bir izin serbest b\u0131rak\u0131lana kadar bekler. \u0130stek tamamland\u0131\u011f\u0131nda, <code>defer apiSemaphore.Release(1)<\/code> ile izin geri verilir.<\/p>\n<h4>Ad\u0131m 2: Toplu \u0130stekleri \u00c7al\u0131\u015ft\u0131rma<\/h4>\n<p>\u015eimdi ana fonksiyonumuzda, bu API isteklerini e\u015fzamanl\u0131 olarak ba\u015flatal\u0131m ve semapforun nas\u0131l \u00e7al\u0131\u015ft\u0131\u011f\u0131n\u0131 g\u00f6zlemleyelim:<\/p>\n<pre><code class=\"language-go\">\nfunc main() {\n    var wg sync.WaitGroup\n\n    fmt.Printf(\"Toplam %d istek, maksimum %d e\u015fzamanl\u0131l\u0131k ile g\u00f6nderiliyor.\\n\", totalRequests, maxConcurrentRequests)\n\n    for i := 1; i <= totalRequests; i++ {\n        wg.Add(1)\n        go func(id int) {\n            defer wg.Done()\n            result, err := simulateAPIRequest(id)\n            if err != nil {\n                fmt.Printf(\"Hata: %v\\n\", err)\n            } else {\n                fmt.Println(result)\n            }\n        }(i)\n    }\n\n    wg.Wait() \/\/ T\u00fcm goroutine'lerin bitmesini bekliyoruz\n    fmt.Println(\"T\u00fcm API istekleri tamamland\u0131.\")\n}\n<\/pre>\n<p><\/code><\/p>\n<p><code>main<\/code> fonksiyonunda, <code>totalRequests<\/code> kadar <code>goroutine<\/code> ba\u015flat\u0131yoruz. Her <code>goroutine<\/code> kendi <code>simulateAPIRequest<\/code> \u00e7a\u011fr\u0131s\u0131n\u0131 yapar. Semapfor sayesinde, ayn\u0131 anda en fazla <code>maxConcurrentRequests<\/code> kadar <code>simulateAPIRequest<\/code> fonksiyonu aktif olarak \u00e7al\u0131\u015facakt\u0131r. Di\u011fer <code>goroutine<\/code>'ler, semapfordan izin alana kadar bekleyecektir. Bu yap\u0131, hem API'nin rate limitlerine sayg\u0131 duyman\u0131z\u0131 sa\u011flar hem de uygulaman\u0131z\u0131n a\u015f\u0131r\u0131 kaynak t\u00fcketmesini \u00f6nler. \u00d6zellikle b\u00fcy\u00fck \u00f6l\u00e7ekli veri senkronizasyonlar\u0131, toplu g\u00fcncellemeler veya web kaz\u0131ma (web scraping) gibi senaryolarda bu desen hayat kurtar\u0131c\u0131 olabilir. Semapforun mevcut izinlerini (<code>apiSemaphore.Available()<\/code>) g\u00f6stererek, aktif e\u015fzamanl\u0131l\u0131k durumunu izleyebilir ve sistemin nas\u0131l d\u00fczenli bir \u015fekilde \u00e7al\u0131\u015ft\u0131\u011f\u0131n\u0131 g\u00f6zlemleyebiliriz. Bu, uygulaman\u0131z\u0131n kararl\u0131l\u0131\u011f\u0131n\u0131 ve g\u00fcvenilirli\u011fini \u00f6nemli \u00f6l\u00e7\u00fcde art\u0131r\u0131r.<\/p>\n<h2>Go'nun <code>sync.WaitGroup<\/code> ve <code>sync.Mutex<\/code> ile Semapfor Farklar\u0131 Nelerdir?<\/h2>\n<p>Go'da e\u015fzamanl\u0131l\u0131k kontrol\u00fc dendi\u011finde akla ilk gelen ara\u00e7lar genellikle <code>sync.WaitGroup<\/code> ve <code>sync.Mutex<\/code> olur. Semapfor da bu kategoride yer alsa da, kullan\u0131m ama\u00e7lar\u0131 ve sunduklar\u0131 kontrol mekanizmalar\u0131 a\u00e7\u0131s\u0131ndan \u00f6nemli farkl\u0131l\u0131klar\u0131 vard\u0131r. Bu b\u00f6l\u00fcmde, bu \u00fc\u00e7 temel e\u015fzamanl\u0131l\u0131k arac\u0131n\u0131 kar\u015f\u0131la\u015ft\u0131rarak, her birinin ne zaman ve neden tercih edilmesi gerekti\u011fini inceleyece\u011fiz.<\/p>\n<h3><code>sync.Mutex<\/code> (Kar\u015f\u0131l\u0131kl\u0131 D\u0131\u015flama Kilidi)<\/h3>\n<p><code>sync.Mutex<\/code>, \"kar\u015f\u0131l\u0131kl\u0131 d\u0131\u015flama kilidi\" anlam\u0131na gelir ve bir payla\u015f\u0131lan kayna\u011fa ayn\u0131 anda yaln\u0131zca bir <code>goroutine<\/code>'in eri\u015fmesine izin verir. En temel e\u015fzamanl\u0131l\u0131k kontrol mekanizmalar\u0131ndan biridir ve kritik b\u00f6l\u00fcmleri (critical sections) korumak i\u00e7in kullan\u0131l\u0131r. E\u011fer bir <code>goroutine<\/code> bir <code>Mutex<\/code>'i kilitlerse (<code>Lock()<\/code>), ba\u015fka bir <code>goroutine<\/code> ayn\u0131 <code>Mutex<\/code>'i kilitlemeye \u00e7al\u0131\u015ft\u0131\u011f\u0131nda, kilit serbest b\u0131rak\u0131lana kadar bloklan\u0131r ve bekler (<code>Unlock()<\/code>).<\/p>\n<ul>\n<li><strong>Kullan\u0131m Amac\u0131:<\/strong> Tek bir payla\u015f\u0131lan kayna\u011fa veya veri yap\u0131s\u0131na ayn\u0131 anda tekil eri\u015fimi garanti etmek. Veri yar\u0131\u015flar\u0131n\u0131 (data races) \u00f6nlemek.<\/li>\n<li><strong>\u00d6rnek Senaryo:<\/strong> Bir harita (<code>map<\/code>) veya dilim (<code>slice<\/code>) gibi payla\u015f\u0131lan bir veri yap\u0131s\u0131n\u0131 g\u00fcncellerken. Bir sayac\u0131 atomik olarak art\u0131r\u0131p azalt\u0131rken.<\/li>\n<li><strong>Kapasite:<\/strong> Kapasitesi 1'dir. Yani, ayn\u0131 anda sadece bir <code>goroutine<\/code> kayna\u011fa eri\u015febilir. Bu y\u00f6n\u00fcyle, kapasitesi 1 olan bir ikili (binary) semapfor gibi d\u00fc\u015f\u00fcn\u00fclebilir.<\/li>\n<\/ul>\n<pre><code class=\"language-go\">\n\/\/ Mutex \u00f6rne\u011fi\ntype Counter struct {\n    mu    sync.Mutex\n    value int\n}\n\nfunc (c *Counter) Increment() {\n    c.mu.Lock()\n    defer c.mu.Unlock()\n    c.value++\n}\n\nfunc (c *Counter) Get() int {\n    c.mu.Lock()\n    defer c.mu.Unlock()\n    return c.value\n}\n<\/pre>\n<p><\/code><\/p>\n<p><code>Mutex<\/code>, en dar ve spesifik eri\u015fim kontrol\u00fcn\u00fc sa\u011flar. E\u011fer amac\u0131n\u0131z sadece bir kayna\u011f\u0131 e\u015fzamanl\u0131 yazma i\u015flemlerinden korumaksa, <code>Mutex<\/code> en uygun ve verimli \u00e7\u00f6z\u00fcmd\u00fcr.<\/p>\n<h3><code>sync.WaitGroup<\/code> (Bekleme Grubu)<\/h3>\n<p><code>sync.WaitGroup<\/code>, bir grup <code>goroutine<\/code>'in tamamlanmas\u0131n\u0131 beklemek i\u00e7in tasarlanm\u0131\u015ft\u0131r. Belirli say\u0131da <code>goroutine<\/code>'i ba\u015flat\u0131rs\u0131n\u0131z ve ana <code>goroutine<\/code>'in t\u00fcm bu <code>goroutine<\/code>'lerin i\u015flerini bitirmesini beklemesini istersiniz. <code>WaitGroup<\/code> bir saya\u00e7 tutar: <code>Add(n)<\/code> ile saya\u00e7 art\u0131r\u0131l\u0131r (n kadar goroutine eklendi), <code>Done()<\/code> ile saya\u00e7 azalt\u0131l\u0131r (bir goroutine i\u015fini bitirdi) ve <code>Wait()<\/code> ile saya\u00e7 s\u0131f\u0131r olana kadar beklenir.<\/p>\n<ul>\n<li><strong>Kullan\u0131m Amac\u0131:<\/strong> Bir grup e\u015fzamanl\u0131 g\u00f6revin tamamlanmas\u0131n\u0131 senkronize etmek. Paralel i\u015flemleri ba\u015flat\u0131p t\u00fcm\u00fcn\u00fcn bitmesini beklemek.<\/li>\n<li><strong>\u00d6rnek Senaryo:<\/strong> Birden fazla dosyay\u0131 paralel olarak indirip t\u00fcm indirmelerin bitmesini beklemek. Bir i\u015f listesini birden fazla <code>worker<\/code> <code>goroutine<\/code> aras\u0131nda da\u011f\u0131t\u0131p t\u00fcm <code>worker<\/code>'lar\u0131n i\u015fini tamamlamas\u0131n\u0131 beklemek.<\/li>\n<li><strong>Kapasite:<\/strong> Do\u011frudan bir kaynak eri\u015fim kapasitesi s\u0131n\u0131rlamas\u0131 sunmaz. Sadece \"bekleme\" mant\u0131\u011f\u0131yla ilgilenir.<\/li>\n<\/ul>\n<pre><code class=\"language-go\">\n\/\/ WaitGroup \u00f6rne\u011fi\nfunc main() {\n    var wg sync.WaitGroup\n    for i := 0; i < 5; i++ {\n        wg.Add(1)\n        go func(id int) {\n            defer wg.Done()\n            fmt.Printf(\"G\u00f6rev %d \u00e7al\u0131\u015f\u0131yor...\\n\", id)\n            time.Sleep(time.Second)\n            fmt.Printf(\"G\u00f6rev %d tamamland\u0131.\\n\", id)\n        }(i)\n    }\n    wg.Wait()\n    fmt.Println(\"T\u00fcm g\u00f6revler bitti.\")\n}\n<\/pre>\n<p><\/code><\/p>\n<p><code>WaitGroup<\/code>, ak\u0131\u015f\u0131 kontrol etmekten ziyade, tamamlanmay\u0131 beklemek i\u00e7in kullan\u0131l\u0131r. Kaynak eri\u015fimini k\u0131s\u0131tlamaz, sadece \"t\u00fcm bu i\u015fler bitene kadar bekle\" der.<\/p>\n<h3>Semapfor (S\u0131n\u0131rl\u0131 Kaynak Eri\u015fimi)<\/h3>\n<p>Semapfor, belirli bir payla\u015f\u0131lan kayna\u011fa ayn\u0131 anda eri\u015febilecek <code>goroutine<\/code> say\u0131s\u0131n\u0131 s\u0131n\u0131rlamak i\u00e7in kullan\u0131l\u0131r. Bir sayac\u0131n (izin havuzu) belirli bir kapasitesi vard\u0131r. Bir <code>goroutine<\/code> kayna\u011fa eri\u015fmek i\u00e7in izin ister; e\u011fer izin yoksa bloklan\u0131r. \u0130\u015flem bitti\u011finde izni serbest b\u0131rak\u0131r.<\/p>\n<ul>\n<li><strong>Kullan\u0131m Amac\u0131:<\/strong> Payla\u015f\u0131lan bir kayna\u011fa e\u015fzamanl\u0131 eri\u015fen <code>goroutine<\/code> say\u0131s\u0131n\u0131 s\u0131n\u0131rlamak. Kaynak t\u00fckenmesini \u00f6nlemek, rate limiting yapmak, veritaban\u0131 ba\u011flant\u0131 havuzlar\u0131n\u0131 y\u00f6netmek.<\/li>\n<li><strong>\u00d6rnek Senaryo:<\/strong> Ayn\u0131 anda yaln\u0131zca <code>N<\/code> kadar veritaban\u0131 ba\u011flant\u0131s\u0131n\u0131n a\u00e7\u0131k olmas\u0131na izin vermek. Harici bir API'ye ayn\u0131 anda yaln\u0131zca <code>M<\/code> kadar istek g\u00f6ndermek.<\/li>\n<li><strong>Kapasite:<\/strong> Tan\u0131mland\u0131\u011f\u0131 kapasiteye (<code>N<\/code>) kadar e\u015fzamanl\u0131 eri\u015fime izin verir. <code>N > 1<\/code> ise say\u0131c\u0131 semapfor, <code>N = 1<\/code> ise ikili semapfor (<code>Mutex<\/code>'e benzer) olur.<\/li>\n<\/ul>\n<pre><code class=\"language-go\">\n\/\/ Semapfor \u00f6rne\u011fi (kanallar ile)\ntype Semaphore chan struct{}\n\nfunc NewSemaphore(capacity int) Semaphore {\n    return make(chan struct{}, capacity)\n}\n\nfunc (s Semaphore) Acquire() { s <- struct{}{} }\nfunc (s Semaphore) Release() { <-s }\n\nfunc main() {\n    sem := NewSemaphore(3) \/\/ Ayn\u0131 anda 3 goroutine'e izin ver\n    var wg sync.WaitGroup\n\n    for i := 0; i < 10; i++ {\n        wg.Add(1)\n        go func(id int) {\n            defer wg.Done()\n            sem.Acquire() \/\/ \u0130zin al\n            defer sem.Release() \/\/ \u0130zni b\u0131rak\n            fmt.Printf(\"G\u00f6rev %d semapfordan izin ald\u0131, \u00e7al\u0131\u015f\u0131yor...\\n\", id)\n            time.Sleep(2 * time.Second)\n            fmt.Printf(\"G\u00f6rev %d tamamland\u0131.\\n\", id)\n        }(i)\n    }\n    wg.Wait()\n    fmt.Println(\"T\u00fcm g\u00f6revler semapfor ile kontrol edildi ve tamamland\u0131.\")\n}\n<\/pre>\n<p><\/code><\/p>\n<p><strong>\u00d6zetle:<\/strong><\/p>\n<table style=\"width:100%; border-collapse: collapse;\">\n<thead>\n<tr>\n<th style=\"border: 1px solid #ddd; padding: 8px; text-align: left;\">\u00d6zellik<\/th>\n<th style=\"border: 1px solid #ddd; padding: 8px; text-align: left;\"><code>sync.Mutex<\/code><\/th>\n<th style=\"border: 1px solid #ddd; padding: 8px; text-align: left;\"><code>sync.WaitGroup<\/code><\/th>\n<th style=\"border: 1px solid #ddd; padding: 8px; text-align: left;\">Semapfor<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td style=\"border: 1px solid #ddd; padding: 8px;\"><strong>Temel Ama\u00e7<\/strong><\/td>\n<td style=\"border: 1px solid #ddd; padding: 8px;\">Tekil kaynak eri\u015fimi<\/td>\n<td style=\"border: 1px solid #ddd; padding: 8px;\">G\u00f6revlerin bitmesini bekleme<\/td>\n<td style=\"border: 1px solid #ddd; padding: 8px;\">E\u015fzamanl\u0131 eri\u015fim say\u0131s\u0131n\u0131 s\u0131n\u0131rlama<\/td>\n<\/tr>\n<tr>\n<td style=\"border: 1px solid #ddd; padding: 8px;\"><strong>Kapasite Kontrol\u00fc<\/strong><\/td>\n<td style=\"border: 1px solid #ddd; padding: 8px;\">1 (\u0130kili)<\/td>\n<td style=\"border: 1px solid #ddd; padding: 8px;\">Yok<\/td>\n<td style=\"border: 1px solid #ddd; padding: 8px;\">N (Say\u0131c\u0131)<\/td>\n<\/tr>\n<tr>\n<td style=\"border: 1px solid #ddd; padding: 8px;\"><strong>Bloklama Mekanizmas\u0131<\/strong><\/td>\n<td style=\"border: 1px solid #ddd; padding: 8px;\">Kilit serbest b\u0131rak\u0131lana kadar<\/td>\n<td style=\"border: 1px solid #ddd; padding: 8px;\">Saya\u00e7 s\u0131f\u0131r olana kadar<\/td>\n<td style=\"border: 1px solid #ddd; padding: 8px;\">\u0130zin serbest b\u0131rak\u0131lana kadar<\/td>\n<\/tr>\n<tr>\n<td style=\"border: 1px solid #ddd; padding: 8px;\"><strong>Kullan\u0131m Alan\u0131<\/strong><\/td>\n<td style=\"border: 1px solid #ddd; padding: 8px;\">Payla\u015f\u0131lan veri yap\u0131lar\u0131n\u0131 koruma<\/td>\n<td style=\"border: 1px solid #ddd; padding: 8px;\">Paralel g\u00f6revlerin tamamlanmas\u0131n\u0131 senkronize etme<\/td>\n<td style=\"border: 1px solid #ddd; padding: 8px;\">Rate limiting, kaynak havuzlar\u0131<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>Go'da e\u015fzamanl\u0131l\u0131k \u00e7\u00f6z\u00fcmleri genellikle bu \u00fc\u00e7 arac\u0131n bir kombinasyonunu gerektirir. Do\u011fru arac\u0131 do\u011fru senaryoda kullanmak, uygulaman\u0131z\u0131n performans\u0131n\u0131 ve kararl\u0131l\u0131\u011f\u0131n\u0131 do\u011frudan etkileyecektir. Semapfor, \u00f6zellikle belirli bir kapasite s\u0131n\u0131rland\u0131rmas\u0131 gerektiren durumlarda, di\u011fer iki ara\u00e7tan farkl\u0131 ve kritik bir rol oynar.<\/p>\n<h2>Geli\u015fmi\u015f Semapfor Kullan\u0131mlar\u0131 ve Dikkat Edilmesi Gerekenler Nelerdir?<\/h2>\n<p>Basit semapfor uygulamalar\u0131n\u0131n \u00f6tesine ge\u00e7erek, daha karma\u015f\u0131k senaryolarda semapforlar\u0131 nas\u0131l daha verimli kullanabilece\u011fimizi ve olas\u0131 tuzaklardan nas\u0131l ka\u00e7\u0131naca\u011f\u0131m\u0131z\u0131 inceleyelim. Go'nun <code>context<\/code> paketi ve semapforlar\u0131 birle\u015ftirmek, daha esnek ve hata toleransl\u0131 sistemler olu\u015fturmam\u0131za olanak tan\u0131r.<\/p>\n<h3>Zaman A\u015f\u0131m\u0131 (Timeout) ile \u0130zin Alma<\/h3>\n<p>Bazen, bir <code>goroutine<\/code>'in bir semapfordan izin almak i\u00e7in sonsuza kadar beklemesini istemeyiz. \u00d6zellikle kullan\u0131c\u0131 aray\u00fcz\u00fc yan\u0131t verebilirli\u011fini korumak veya a\u011f istekleri gibi zamana ba\u011fl\u0131 i\u015flemlerde, belirli bir s\u00fcre i\u00e7inde izin al\u0131namazsa i\u015flemin iptal edilmesi gerekebilir. <code>golang.org\/x\/sync\/semaphore<\/code> paketi, <code>context<\/code> ile bu t\u00fcr zaman a\u015f\u0131mlar\u0131n\u0131 kolayca y\u00f6netmemizi sa\u011flar.<\/p>\n<pre><code class=\"language-go\">\npackage main\n\nimport (\n    \"context\"\n    \"fmt\"\n    \"log\"\n    \"time\"\n\n    \"golang.org\/x\/sync\/semaphore\"\n)\n\nfunc main() {\n    sem := semaphore.NewWeighted(2) \/\/ Maksimum 2 e\u015fzamanl\u0131 izin\n    \n    \/\/ \u0130lk iki g\u00f6revi ba\u015flat\u0131yoruz (izinleri alacaklar)\n    go func() {\n        sem.Acquire(context.Background(), 1)\n        fmt.Println(\"G\u00f6rev 1 ba\u015flad\u0131 (izin al\u0131nd\u0131)...\")\n        time.Sleep(3 * time.Second)\n        fmt.Println(\"G\u00f6rev 1 bitti, izin serbest.\")\n        sem.Release(1)\n    }()\n\n    go func() {\n        sem.Acquire(context.Background(), 1)\n        fmt.Println(\"G\u00f6rev 2 ba\u015flad\u0131 (izin al\u0131nd\u0131)...\")\n        time.Sleep(3 * time.Second)\n        fmt.Println(\"G\u00f6rev 2 bitti, izin serbest.\")\n        sem.Release(1)\n    }()\n\n    time.Sleep(500 * time.Millisecond) \/\/ \u0130lk iki g\u00f6revin ba\u015flamas\u0131na izin ver\n\n    \/\/ \u00dc\u00e7\u00fcnc\u00fc g\u00f6revi zaman a\u015f\u0131m\u0131 ile ba\u015flat\u0131yoruz\n    ctx, cancel := context.WithTimeout(context.Background(), 1*time.Second)\n    defer cancel()\n\n    fmt.Println(\"G\u00f6rev 3: 1 saniye i\u00e7inde izin almaya \u00e7al\u0131\u015f\u0131l\u0131yor...\")\n    if err := sem.Acquire(ctx, 1); err != nil {\n        if err == context.DeadlineExceeded {\n            log.Println(\"G\u00f6rev 3: \u0130zin al\u0131namad\u0131, zaman a\u015f\u0131m\u0131!\")\n        } else {\n            log.Printf(\"G\u00f6rev 3: Hata olu\u015ftu: %v\\n\", err)\n        }\n    } else {\n        defer sem.Release(1)\n        fmt.Println(\"G\u00f6rev 3 ba\u015flad\u0131 (izin al\u0131nd\u0131)...\")\n        time.Sleep(1 * time.Second)\n        fmt.Println(\"G\u00f6rev 3 bitti, izin serbest.\")\n    }\n\n    time.Sleep(4 * time.Second) \/\/ T\u00fcm g\u00f6revlerin bitmesini beklemek i\u00e7in\n    fmt.Println(\"Ana program tamamland\u0131.\")\n}\n<\/pre>\n<p><\/code><\/p>\n<p>Bu \u00f6rnekte, \u00fc\u00e7\u00fcnc\u00fc g\u00f6rev 1 saniyelik bir zaman a\u015f\u0131m\u0131 ile izin almaya \u00e7al\u0131\u015f\u0131r. E\u011fer bu s\u00fcre i\u00e7inde bir izin serbest b\u0131rak\u0131lmazsa, <code>Acquire<\/code> fonksiyonu <code>context.DeadlineExceeded<\/code> hatas\u0131 ile d\u00f6ner ve g\u00f6rev iptal edilir. Bu, uygulaman\u0131z\u0131n donmu\u015f (stuck) kalmas\u0131n\u0131 \u00f6nler ve kullan\u0131c\u0131ya daha iyi bir deneyim sunar.<\/p>\n<h3>\u0130ptal Edilebilir \u0130\u015flemler i\u00e7in <code>Context<\/code> Kullan\u0131m\u0131<\/h3>\n<p>Zaman a\u015f\u0131m\u0131na benzer \u015fekilde, bir i\u015flem genel olarak iptal edildi\u011finde (\u00f6rne\u011fin, bir sunucu kapan\u0131rken veya kullan\u0131c\u0131 bir i\u015flemi durdurdu\u011funda) semapfordan bekleyen <code>goroutine<\/code>'lerin de iptal edilmesini isteyebiliriz. <code>context.WithCancel<\/code> ile olu\u015fturulan bir <code>context<\/code>, bu senaryo i\u00e7in idealdir.<\/p>\n<pre><code class=\"language-go\">\n\/\/ ... (paket ve import'lar ayn\u0131) ...\n\nfunc main() {\n    sem := semaphore.NewWeighted(1) \/\/ Maksimum 1 e\u015fzamanl\u0131 izin\n    ctx, cancel := context.WithCancel(context.Background())\n\n    go func() {\n        fmt.Println(\"Uzun s\u00fcreli g\u00f6rev ba\u015flat\u0131ld\u0131...\")\n        if err := sem.Acquire(ctx, 1); err != nil {\n            log.Printf(\"Uzun s\u00fcreli g\u00f6rev izin alamad\u0131: %v\\n\", err)\n            return\n        }\n        defer sem.Release(1)\n        \n        select {\n        case <-time.After(5 * time.Second):\n            fmt.Println(\"Uzun s\u00fcreli g\u00f6rev tamamland\u0131.\")\n        case <-ctx.Done():\n            fmt.Println(\"Uzun s\u00fcreli g\u00f6rev iptal edildi.\")\n        }\n    }()\n\n    time.Sleep(1 * time.Second)\n    fmt.Println(\"Ba\u015fka bir g\u00f6rev i\u00e7in izin al\u0131nmaya \u00e7al\u0131\u015f\u0131l\u0131yor (1. izin kullan\u0131mda)...\")\n    \n    \/\/ \u0130kinci bir goroutine izin almaya \u00e7al\u0131\u015f\u0131yor, ancak uzun s\u00fcreli g\u00f6rev izni tutuyor.\n    go func() {\n        if err := sem.Acquire(ctx, 1); err != nil {\n            log.Printf(\"K\u0131sa s\u00fcreli g\u00f6rev izin alamad\u0131: %v\\n\", err)\n            return\n        }\n        defer sem.Release(1)\n        fmt.Println(\"K\u0131sa s\u00fcreli g\u00f6rev izin ald\u0131 ve bitti.\")\n    }()\n\n    time.Sleep(2 * time.Second)\n    fmt.Println(\"Ana programdan iptal sinyali g\u00f6nderiliyor...\")\n    cancel() \/\/ Context'i iptal et\n\n    time.Sleep(1 * time.Second) \/\/ G\u00f6revlerin tepki vermesi i\u00e7in k\u0131sa bir s\u00fcre bekle\n    fmt.Println(\"Ana program tamamland\u0131.\")\n}\n<\/pre>\n<p><\/code><\/p>\n<p>Bu \u00f6rnekte, <code>cancel()<\/code> \u00e7a\u011fr\u0131ld\u0131\u011f\u0131nda, <code>ctx.Done()<\/code> kanal\u0131 kapan\u0131r. Hem izin almaya \u00e7al\u0131\u015fan hem de izin alm\u0131\u015f olan <code>goroutine<\/code>'ler bu durumu alg\u0131layarak i\u015flemlerini durdurabilir veya temizleme yapabilir. Bu, sisteminizin daha reaktif ve kontroll\u00fc olmas\u0131n\u0131 sa\u011flar.<\/p>\n<div class=\"expert-tip\">\n  Uzman \u0130pucu: <code>context.Context<\/code> kullan\u0131m\u0131, e\u015fzamanl\u0131 Go uygulamalar\u0131nda hata y\u00f6netimini ve iptal mekanizmalar\u0131n\u0131 merkezi bir \u015fekilde ele alman\u0131z\u0131 sa\u011flar. Semapforlarla birle\u015fti\u011finde, kaynak kontrol\u00fc \u00e7ok daha sa\u011flam hale gelir.\n<\/div>\n<h3>Dikkat Edilmesi Gerekenler: Deadlock'lardan Ka\u00e7\u0131nma<\/h3>\n<p>Semapforlar g\u00fc\u00e7l\u00fc ara\u00e7lar olsa da, yanl\u0131\u015f kullan\u0131ld\u0131\u011f\u0131nda kilitlenmelere (deadlock) yol a\u00e7abilir. \u0130\u015fte baz\u0131 \u00f6nemli noktalar:<\/p>\n<ol>\n<li><strong>Asla \u0130zni Serbest B\u0131rakmay\u0131 Unutmay\u0131n:<\/strong> Bir <code>goroutine<\/code> izni ald\u0131ktan sonra, i\u015fi bitti\u011finde veya bir hata olu\u015ftu\u011funda <code>Release()<\/code> etmeyi unutursa, o izin sonsuza kadar kilitli kal\u0131r ve di\u011fer <code>goroutine<\/code>'ler beklemeye devam eder. <code>defer sem.Release(1)<\/code> kullan\u0131m\u0131 bu durumun \u00f6n\u00fcne ge\u00e7mek i\u00e7in \u015fiddetle tavsiye edilir.<\/li>\n<li><strong>A\u015f\u0131r\u0131 \u0130\u00e7 \u0130\u00e7e Semapfor Kullan\u0131m\u0131ndan Ka\u00e7\u0131n\u0131n:<\/strong> Birden fazla semapforu i\u00e7 i\u00e7e kullan\u0131rken dikkatli olun. E\u011fer <code>goroutine<\/code>'ler semapforlar\u0131 farkl\u0131 s\u0131ralarda almaya \u00e7al\u0131\u015f\u0131rsa (\u00f6rne\u011fin, birisi A sonra B'yi al\u0131rken, di\u011feri B sonra A'y\u0131 al\u0131r), deadlock olu\u015fabilir. Bu t\u00fcr durumlarda, kilit s\u0131ralama (lock ordering) prensibini uygulay\u0131n.<\/li>\n<li><strong>Yeterli Kapasiteyi Belirleyin:<\/strong> Semapfor kapasitesi \u00e7ok d\u00fc\u015f\u00fck belirlenirse, e\u015fzamanl\u0131l\u0131k avantajlar\u0131ndan yeterince yararlan\u0131lamaz ve performans d\u00fc\u015febilir. \u00c7ok y\u00fcksek belirlenirse, semapforun amac\u0131 bo\u015fa \u00e7\u0131kabilir ve kaynak t\u00fckenmesi riski artabilir. Sisteminizi test ederek optimal kapasiteyi bulmaya \u00e7al\u0131\u015f\u0131n.<\/li>\n<li><strong>Hata Y\u00f6netimi ve Temizleme:<\/strong> <code>Acquire<\/code> \u00e7a\u011fr\u0131s\u0131 hata d\u00f6nd\u00fcrebilir (\u00f6zellikle <code>context<\/code> kullan\u0131ld\u0131\u011f\u0131nda). Bu hatalar\u0131 d\u00fczg\u00fcn bir \u015fekilde ele al\u0131n ve gerekirse kaynaklar\u0131 temizleyin.<\/li>\n<\/ol>\n<p>Geli\u015fmi\u015f senaryolarda semapforlar\u0131 dikkatlice tasarlamak ve test etmek, sa\u011flam ve performansl\u0131 Go uygulamalar\u0131 olu\u015fturman\u0131n anahtar\u0131d\u0131r. Bu teknikleri uygulayarak ve potansiyel tuzaklardan ka\u00e7\u0131narak, Go'da e\u015fzamanl\u0131l\u0131k kontrol\u00fcn\u00fc bir \u00fcst seviyeye ta\u015f\u0131yabilirsiniz.<\/p>\n<h2>Mobil Cihazlar \u0130\u00e7in Semapfor Uygulamalar\u0131: Performans Optimizasyonu<\/h2>\n<p>Go, mobil uygulama geli\u015ftirmede (\u00f6zellikle Android ve iOS i\u00e7in <code>gomobile<\/code> veya Go'yu bir k\u00fct\u00fcphane olarak kullanarak) giderek daha fazla ilgi g\u00f6r\u00fcyor. Mobil cihazlarda kaynaklar, sunucu ortamlar\u0131na k\u0131yasla \u00e7ok daha k\u0131s\u0131tl\u0131d\u0131r: i\u015flemci g\u00fcc\u00fc, bellek, batarya \u00f6mr\u00fc ve a\u011f bant geni\u015fli\u011fi \u00f6nemli s\u0131n\u0131rlay\u0131c\u0131 fakt\u00f6rlerdir. Bu nedenle, Go'nun e\u015fzamanl\u0131l\u0131k yeteneklerini mobil platformlarda kullan\u0131rken semapfor desenini ak\u0131ll\u0131ca uygulamak, performans ve kullan\u0131c\u0131 deneyimi a\u00e7\u0131s\u0131ndan kritik \u00f6neme sahiptir.<\/p>\n<h3>Neden Mobil Ortamda Semapfor \u00d6nemlidir?<\/h3>\n<ol>\n<li><strong>Batarya Tasarrufu:<\/strong> A\u015f\u0131r\u0131 e\u015fzamanl\u0131 g\u00f6revler, CPU'yu daha uzun s\u00fcre y\u00fcksek kullan\u0131mda tutarak batarya \u00f6mr\u00fcn\u00fc \u00f6nemli \u00f6l\u00e7\u00fcde azaltabilir. Semapfor ile e\u015fzamanl\u0131 g\u00f6rev say\u0131s\u0131n\u0131 s\u0131n\u0131rlamak, CPU y\u00fck\u00fcn\u00fc dengeleyerek batarya tasarrufuna yard\u0131mc\u0131 olur.<\/li>\n<li><strong>Bellek Y\u00f6netimi:<\/strong> Her <code>goroutine<\/code>, k\u00fc\u00e7\u00fck olsa da bir miktar bellek t\u00fcketir. Y\u00fczlerce veya binlerce <code>goroutine<\/code>'in ayn\u0131 anda \u00e7al\u0131\u015fmas\u0131, mobil cihazlarda bellek t\u00fckenmesine ve uygulaman\u0131n \u00e7\u00f6kmesine neden olabilir. Semapforlar, aktif <code>goroutine<\/code> say\u0131s\u0131n\u0131 s\u0131n\u0131rlayarak bellek ayak izini kontrol alt\u0131nda tutar.<\/li>\n<li><strong>A\u011f Eri\u015fimi Kontrol\u00fc:<\/strong> Mobil uygulamalar genellikle a\u011f \u00fczerinden veri al\u0131\u015fveri\u015fi yapar. Ancak mobil a\u011flar de\u011fi\u015fken h\u0131zlarda ve s\u0131n\u0131rl\u0131 bant geni\u015fli\u011finde olabilir. Semapfor kullanarak ayn\u0131 anda g\u00f6nderilen a\u011f iste\u011fi say\u0131s\u0131n\u0131 limitlemek, hem a\u011f\u0131n a\u015f\u0131r\u0131 y\u00fcklenmesini \u00f6nler hem de yava\u015f a\u011flarda dahi uygulaman\u0131n yan\u0131t verebilirli\u011fini korur.<\/li>\n<li><strong>Kullan\u0131c\u0131 Deneyimi:<\/strong> Kaynaklar\u0131n a\u015f\u0131r\u0131 kullan\u0131lmas\u0131, uygulaman\u0131n donmas\u0131na, yava\u015flamas\u0131na ve genel kullan\u0131c\u0131 deneyiminin d\u00fc\u015fmesine yol a\u00e7ar. Semapforlar, kritik kaynaklar\u0131n d\u00fczg\u00fcn y\u00f6netilmesini sa\u011flayarak uygulaman\u0131n ak\u0131c\u0131 kalmas\u0131na yard\u0131mc\u0131 olur.<\/li>\n<\/ol>\n<h3>Mobil Uygulamalarda Semapfor Kullan\u0131m Senaryolar\u0131<\/h3>\n<p>Mobil uygulamalarda semapforlar\u0131 kullanabilece\u011fimiz baz\u0131 ger\u00e7ek\u00e7i senaryolar:<\/p>\n<ul>\n<li><strong>G\u00f6rsel Y\u00fckleme Limitleri:<\/strong> Bir resim galerisi uygulamas\u0131nda, ayn\u0131 anda sadece belirli say\u0131da y\u00fcksek \u00e7\u00f6z\u00fcn\u00fcrl\u00fckl\u00fc g\u00f6rselin indirilip i\u015flenmesine izin vermek.<\/li>\n<li><strong>Veritaban\u0131 \u0130\u015flemleri:<\/strong> Yerel SQLite veya Realm veritaban\u0131 gibi g\u00f6m\u00fcl\u00fc veritabanlar\u0131na ayn\u0131 anda birden fazla yazma i\u015flemini kontrol alt\u0131nda tutmak.<\/li>\n<li><strong>Senkronizasyon G\u00f6revleri:<\/strong> Arka planda sunucu ile veri senkronizasyonu yaparken, batarya ve a\u011f kullan\u0131m\u0131n\u0131 optimize etmek i\u00e7in e\u015fzamanl\u0131 senkronizasyon g\u00f6revlerinin say\u0131s\u0131n\u0131 s\u0131n\u0131rlamak.<\/li>\n<li><strong>Kullan\u0131c\u0131 Aray\u00fcz\u00fc G\u00fcncellemeleri:<\/strong> Yo\u011fun veri i\u015fleme g\u00f6revlerinin ana UI i\u015f par\u00e7ac\u0131\u011f\u0131n\u0131 (main thread) bloklamas\u0131n\u0131 \u00f6nlemek i\u00e7in, bu g\u00f6revlerin i\u015fleme kapasitesini semapfor ile s\u0131n\u0131rlamak.<\/li>\n<\/ul>\n<h3>Mobil \u0130\u00e7in \u00d6rnek: Resim Y\u00fckleme Kuyru\u011fu<\/h3>\n<p>A\u015fa\u011f\u0131daki \u00f6rnek, ayn\u0131 anda sadece belirli say\u0131da resmin indirilece\u011fi ve i\u015flenece\u011fi bir mobil uygulama senaryosunu g\u00f6sterir. Bu, mobil cihaz\u0131n kaynaklar\u0131n\u0131 korumak ve kullan\u0131c\u0131 aray\u00fcz\u00fcn\u00fcn ak\u0131c\u0131 kalmas\u0131n\u0131 sa\u011flamak i\u00e7in \u00f6nemlidir.<\/p>\n<pre><code class=\"language-go\">\npackage main\n\nimport (\n    \"context\"\n    \"fmt\"\n    \"log\"\n    \"sync\"\n    \"time\"\n\n    \"golang.org\/x\/sync\/semaphore\"\n)\n\nconst (\n    maxConcurrentImageDownloads = 3 \/\/ Ayn\u0131 anda indirilecek maksimum resim say\u0131s\u0131\n    totalImagesToDownload       = 10\n)\n\n\/\/ downloadImage, bir resim indirme i\u015flemini sim\u00fcle eder.\nfunc downloadImage(ctx context.Context, imageURL string, id int) error {\n    select {\n    case <-ctx.Done():\n        return fmt.Errorf(\"resim %d indirme i\u015flemi iptal edildi: %w\", id, ctx.Err())\n    default:\n        fmt.Printf(\"Resim %d (%s) indirilmeye ba\u015fland\u0131...\\n\", id, imageURL)\n        time.Sleep(time.Duration(2+id%3) * time.Second) \/\/ \u0130ndirme s\u00fcresi sim\u00fclasyonu\n        fmt.Printf(\"Resim %d (%s) indirildi.\\n\", id, imageURL)\n        return nil\n    }\n}\n\nfunc main() {\n    sem := semaphore.NewWeighted(maxConcurrentImageDownloads)\n    var wg sync.WaitGroup\n    ctx, cancel := context.WithCancel(context.Background())\n    defer cancel()\n\n    fmt.Printf(\"Toplam %d resim indirilecek, maksimum %d e\u015fzamanl\u0131.\\n\", totalImagesToDownload, maxConcurrentImageDownloads)\n\n    for i := 0; i < totalImagesToDownload; i++ {\n        wg.Add(1)\n        go func(id int) {\n            defer wg.Done()\n\n            \/\/ \u0130ndirme i\u015fleminden \u00f6nce semapfordan izin al\n            if err := sem.Acquire(ctx, 1); err != nil {\n                log.Printf(\"Resim %d i\u00e7in izin al\u0131namad\u0131: %v\\n\", id, err)\n                return\n            }\n            defer sem.Release(1) \/\/ \u0130ndirme bitince izni serbest b\u0131rak\n\n            imageURL := fmt.Sprintf(\"https:\/\/example.com\/image-%d.jpg\", id)\n            if err := downloadImage(ctx, imageURL, id); err != nil {\n                log.Printf(\"Resim %d indirme hatas\u0131: %v\\n\", id, err)\n            }\n        }(i)\n    }\n\n    \/\/ \u0130sterseniz burada belli bir s\u00fcre sonra t\u00fcm indirmeleri iptal edebilirsiniz\n    \/\/ go func() {\n    \/\/     time.Sleep(5 * time.Second)\n    \/\/     fmt.Println(\"5 saniye sonra indirme i\u015flemleri iptal ediliyor...\")\n    \/\/     cancel()\n    \/\/ }()\n\n    wg.Wait()\n    fmt.Println(\"T\u00fcm resim indirme g\u00f6revleri tamamland\u0131.\")\n}\n<\/pre>\n<p><\/code><\/p>\n<h3>Mobil Uyumlu Tasar\u0131m \u0130pu\u00e7lar\u0131 ve CSS Media Query \u00d6rne\u011fi<\/h3>\n<p>Mobil uygulamalar genellikle sadece i\u015f mant\u0131\u011f\u0131n\u0131 i\u00e7erir ve kullan\u0131c\u0131 aray\u00fcz\u00fc yerel (native) platformlarda (Kotlin\/Java, Swift\/Objective-C) olu\u015fturulur. Ancak, Go ile bir web g\u00f6r\u00fcn\u00fcm\u00fc (webview) olu\u015fturuyorsan\u0131z veya Go ile olu\u015fturdu\u011funuz bir hizmetin web tabanl\u0131 bir y\u00f6netim aray\u00fcz\u00fc varsa, mobil uyumlu HTML\/CSS \u00f6nemlidir.<\/p>\n<p>CSS Media Query'ler, cihaz\u0131n ekran boyutuna g\u00f6re farkl\u0131 stiller uygulaman\u0131z\u0131 sa\u011flar. \u00d6rne\u011fin, k\u00fc\u00e7\u00fck ekranlarda daha az s\u00fctunlu bir d\u00fczen g\u00f6stermek isteyebilirsiniz:<\/p>\n<pre><code class=\"language-css\">\n\/* Genel stil *\/\n.container {\n    display: grid;\n    grid-template-columns: repeat(4, 1fr); \/* Varsay\u0131lan olarak 4 s\u00fctun *\/\n    gap: 20px;\n    padding: 10px;\n}\n\n.item {\n    border: 1px solid #ccc;\n    padding: 15px;\n    text-align: center;\n}\n\n\/* Mobil cihazlar i\u00e7in (ekran geni\u015fli\u011fi 768px veya daha az) *\/\n@media screen and (max-width: 768px) {\n    .container {\n        grid-template-columns: repeat(2, 1fr); \/* Orta boyutlu ekranlarda 2 s\u00fctun *\/\n    }\n}\n\n\/* \u00c7ok k\u00fc\u00e7\u00fck mobil cihazlar i\u00e7in (ekran geni\u015fli\u011fi 480px veya daha az) *\/\n@media screen and (max-width: 480px) {\n    .container {\n        grid-template-columns: 1fr; \/* K\u00fc\u00e7\u00fck ekranlarda tek s\u00fctun *\/\n    }\n}\n<\/pre>\n<p><\/code><\/p>\n<p>Bu CSS kurallar\u0131, bir webview i\u00e7inde veya bir web servisinin d\u00f6nd\u00fcrd\u00fc\u011f\u00fc HTML i\u00e7eri\u011finde kullan\u0131ld\u0131\u011f\u0131nda, Go ile geli\u015ftirilen uygulaman\u0131z\u0131n farkl\u0131 mobil ekran boyutlar\u0131na duyarl\u0131 olmas\u0131n\u0131 sa\u011flar. Mobil uygulamalarda semapforlar\u0131n ve genel kaynak y\u00f6netiminin dikkatli bir \u015fekilde yap\u0131lmas\u0131, uygulaman\u0131n yaln\u0131zca do\u011fru \u00e7al\u0131\u015fmas\u0131n\u0131 de\u011fil, ayn\u0131 zamanda kullan\u0131c\u0131lar i\u00e7in keyifli bir deneyim sunmas\u0131n\u0131 da garantiler.<\/p>\n<h2>Sonu\u00e7: Go'da Semapfor ile E\u015fzamanl\u0131l\u0131\u011f\u0131 Ustaca Y\u00f6netmek<\/h2>\n<p>Bu makalede, Go'da e\u015fzamanl\u0131l\u0131k kontrol\u00fc i\u00e7in semapfor desenini derinlemesine inceledik. Go'nun <code>goroutine<\/code>'ler ve kanallar gibi g\u00fc\u00e7l\u00fc e\u015fzamanl\u0131l\u0131k yap\u0131lar\u0131, paralel programlamay\u0131 kolayla\u015ft\u0131rsa da, s\u0131n\u0131rl\u0131 kaynaklar\u0131n y\u00f6netimi ve potansiyel veri yar\u0131\u015flar\u0131 gibi zorluklar\u0131 da beraberinde getirir. \u0130\u015fte bu noktada semapforlar, belirli bir kayna\u011fa ayn\u0131 anda eri\u015febilecek i\u015flem say\u0131s\u0131n\u0131 kontrol ederek, sistemimizin kararl\u0131, performansl\u0131 ve g\u00fcvenilir olmas\u0131n\u0131 sa\u011flayan temel bir ara\u00e7 olarak \u00f6ne \u00e7\u0131kar.<\/p>\n<p>Ba\u015flang\u0131\u00e7ta Go'nun yerle\u015fik kanallar\u0131n\u0131 kullanarak basit bir semapforun nas\u0131l olu\u015fturulaca\u011f\u0131n\u0131 g\u00f6sterdik, ard\u0131ndan <code>golang.org\/x\/sync\/semaphore<\/code> paketinin sa\u011flad\u0131\u011f\u0131 daha geli\u015fmi\u015f yetenekleri ke\u015ffettik. Ger\u00e7ek d\u00fcnya senaryolar\u0131nda, \u00f6zellikle API rate limiting gibi durumlarda, semapforlar\u0131n ne kadar hayati bir rol oynad\u0131\u011f\u0131n\u0131 pratik bir \u00f6rnekle peki\u015ftirdik. Ayr\u0131ca, <code>sync.Mutex<\/code> ve <code>sync.WaitGroup<\/code> gibi di\u011fer Go e\u015fzamanl\u0131l\u0131k primitifleriyle semapfor aras\u0131ndaki farklar\u0131 a\u00e7\u0131klayarak, her bir arac\u0131n en uygun kullan\u0131m alanlar\u0131n\u0131 belirledik. Son olarak, <code>context<\/code> paketi ile zaman a\u015f\u0131m\u0131 ve iptal mekanizmalar\u0131n\u0131 entegre ederek semapfor kullan\u0131m\u0131n\u0131 daha robust hale getirme ipu\u00e7lar\u0131 sunduk ve mobil uygulamalar gibi k\u0131s\u0131tl\u0131 kaynaklara sahip ortamlarda semapforlar\u0131n neden \u00f6nemli oldu\u011funu vurgulad\u0131k.<\/p>\n<p>Go geli\u015ftiricileri olarak, e\u015fzamanl\u0131l\u0131k kontrol mekanizmalar\u0131n\u0131 anlamak ve do\u011fru bir \u015fekilde uygulamak, karma\u015f\u0131k sistemler in\u015fa ederken vazge\u00e7ilmez bir beceridir. Semapfor deseni, bu ara\u00e7 setinin \u00f6nemli bir par\u00e7as\u0131d\u0131r ve kaynak y\u00f6netiminde, performans optimizasyonunda ve genel sistem kararl\u0131l\u0131\u011f\u0131nda size b\u00fcy\u00fck avantajlar sa\u011flayacakt\u0131r. Unutmay\u0131n, Go'nun felsefesi \"payla\u015fan bellek yerine ileti\u015fim kurarak payla\u015f\" olsa da, bazen payla\u015f\u0131lan kaynaklara kontroll\u00fc eri\u015fim sa\u011flamak i\u00e7in semapfor gibi desenlere ihtiya\u00e7 duyar\u0131z. Bu bilgilerle, Go projelerinizde e\u015fzamanl\u0131l\u0131\u011f\u0131 daha bilin\u00e7li ve etkili bir \u015fekilde y\u00f6netebilece\u011finize inan\u0131yoruz.<\/p>\n<h3>S\u0131k\u00e7a Sorulan Sorular<\/h3>\n<dl>\n<dt>Semapfor ve Mutex aras\u0131ndaki temel fark nedir?<\/dt>\n<dd>\n        <strong>Cevap:<\/strong> <code>sync.Mutex<\/code>, bir kayna\u011fa ayn\u0131 anda yaln\u0131zca <strong>bir<\/strong> <code>goroutine<\/code>'in eri\u015fmesine izin verir (tekil eri\u015fim). Semapfor ise, belirlenen kapasitesine g\u00f6re ayn\u0131 anda <strong>birden fazla<\/strong> <code>goroutine<\/code>'in kayna\u011fa eri\u015fmesine izin verebilir (\u00e7oklu eri\u015fim kontrol\u00fc). Yani, bir <code>Mutex<\/code> asl\u0131nda kapasitesi 1 olan \u00f6zel bir semapfor gibi d\u00fc\u015f\u00fcn\u00fclebilir.\n    <\/dd>\n<dt>Go'da \u00f6zel semapfor (kanallar ile) yerine <code>x\/sync\/semaphore<\/code> paketini ne zaman kullanmal\u0131y\u0131m?<\/dt>\n<dd>\n        <strong>Cevap:<\/strong> Basit ve temel senaryolar i\u00e7in kanallar ile kendi semapforunuzu olu\u015fturmak gayet yeterlidir. Ancak, <code>x\/sync\/semaphore<\/code> paketi, \u00f6zellikle zaman a\u015f\u0131m\u0131 veya iptal edilebilir i\u015flemler i\u00e7in <code>context.Context<\/code> ile entegrasyon, veya g\u00f6revlerin farkl\u0131 \"a\u011f\u0131rl\u0131klara\" sahip oldu\u011fu a\u011f\u0131rl\u0131kl\u0131 semapforlar gibi daha geli\u015fmi\u015f \u00f6zelliklere ihtiyac\u0131n\u0131z oldu\u011funda tercih edilmelidir. Bu paket, daha sa\u011flam ve esnek bir API sunar.\n    <\/dd>\n<dt>Semapfor kullan\u0131rken dikkat etmem gereken en \u00f6nemli risk nedir?<\/dt>\n<dd>\n        <strong>Cevap:<\/strong> En \u00f6nemli risklerden biri, al\u0131nan bir iznin serbest b\u0131rak\u0131lmamas\u0131d\u0131r. E\u011fer bir <code>goroutine<\/code> bir izin al\u0131r ancak <code>Release()<\/code> etmeyi unutursa, o izin sonsuza dek kilitli kal\u0131r ve di\u011fer <code>goroutine<\/code>'ler o izni almak i\u00e7in s\u00fcresizce bekler, bu da bir kilitlenmeye (deadlock) yol a\u00e7ar. Bu riski minimize etmek i\u00e7in <code>defer sem.Release(1)<\/code> kal\u0131b\u0131n\u0131 kullanmak \u00e7ok \u00f6nemlidir.\n    <\/dd>\n<dt>Semapfor ile rate limiting nas\u0131l yap\u0131l\u0131r?<\/dt>\n<dd>\n        <strong>Cevap:<\/strong> Semapfor, e\u015fzamanl\u0131 (concurrent) rate limiting i\u00e7in idealdir. Semapforun kapasitesini, ayn\u0131 anda i\u015flenebilecek maksimum istek say\u0131s\u0131na ayarlars\u0131n\u0131z. Her istek i\u015flenmeden \u00f6nce semapfordan bir izin al\u0131r (<code>Acquire()<\/code>) ve i\u015flendikten sonra izni geri verir (<code>Release()<\/code>). E\u011fer t\u00fcm izinler kullan\u0131mdaysa, yeni istekler izin serbest b\u0131rak\u0131lana kadar otomatik olarak beklemeye al\u0131n\u0131r. Bu, API'lerin e\u015fzamanl\u0131l\u0131k limitlerine uyumu sa\u011flar.\n    <\/dd>\n<dt>Mobil uygulamalarda semapfor kullanman\u0131n avantajlar\u0131 nelerdir?<\/dt>\n<dd>\n        <strong>Cevap:<\/strong> Mobil cihazlarda k\u0131s\u0131tl\u0131 kaynaklar (batarya, bellek, CPU) nedeniyle semapforlar \u00e7ok de\u011ferlidir. E\u015fzamanl\u0131 g\u00f6rev say\u0131s\u0131n\u0131 (\u00f6rne\u011fin, a\u011f istekleri, resim indirmeleri, veritaban\u0131 yazma i\u015flemleri) s\u0131n\u0131rlayarak \u015funlar\u0131 sa\u011flar: batarya \u00f6mr\u00fcn\u00fc uzat\u0131r, bellek t\u00fckenmesini \u00f6nler, CPU a\u015f\u0131r\u0131 y\u00fcklenmesini azalt\u0131r ve uygulaman\u0131n genel yan\u0131t verebilirli\u011fini ve ak\u0131c\u0131l\u0131\u011f\u0131n\u0131 koruyarak daha iyi bir kullan\u0131c\u0131 deneyimi sunar.\n    <\/dd>\n<\/dl>\n","protected":false},"excerpt":{"rendered":"Go programlamada e\u015fzamanl\u0131 kaynak y\u00f6netimi sizi zorluyor mu? Semapfor deseni ile goroutine&#8216;lerinizi etkili bir \u015fekilde senkronize ederek veri&hellip;","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"csco_page_header_type":"","csco_page_load_nextpost":"","csco_page_subscribe_form":"","csco_page_contact_form":"","footnotes":""},"categories":[1],"tags":[],"class_list":{"0":"post-31458","1":"post","2":"type-post","3":"status-publish","4":"format-standard","6":"category-genel","7":"cs-entry","8":"cs-video-wrap"},"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v20.5 (Yoast SEO v25.3.1) - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>Go ile E\u015fzamanl\u0131l\u0131k Kontrol\u00fc: Semapfor Deseni Nas\u0131l Kullan\u0131l\u0131r?<\/title>\n<meta name=\"description\" content=\"Go programlamada e\u015fzamanl\u0131 kaynak y\u00f6netimi sizi zorluyor mu? Semapfor deseni ile goroutine&#039;lerinizi etkili bir \u015fekilde senkronize ederek veri yar\u0131\u015flar\u0131n\u0131 \u00f6nleyebilir ve sisteminizin kararl\u0131l\u0131\u011f\u0131n\u0131 art\u0131rabilirsiniz. Bu rehberde, Go&#039;da semapforun ne oldu\u011funu, neden \u00f6nemli oldu\u011funu ve pratik \u00f6rneklerle nas\u0131l uygulanaca\u011f\u0131n\u0131 ad\u0131m ad\u0131m ke\u015ffedece\u011fiz. Gelin, Go&#039;nun g\u00fc\u00e7l\u00fc e\u015fzamanl\u0131l\u0131k \u00f6zelliklerini semapfor deseniyle nas\u0131l daha verimli kullanabilece\u011finizi birlikte \u00f6\u011frenelim.\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/fatihsoysal.com\/blog\/go-ile-eszamanlilik-kontrolu-semapfor-deseni-nasil-kullanilir\/\" \/>\n<meta property=\"og:locale\" content=\"tr_TR\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Go ile E\u015fzamanl\u0131l\u0131k Kontrol\u00fc: Semapfor Deseni Nas\u0131l Kullan\u0131l\u0131r?\" \/>\n<meta property=\"og:description\" content=\"Go programlamada e\u015fzamanl\u0131 kaynak y\u00f6netimi sizi zorluyor mu? Semapfor deseni ile goroutine&#039;lerinizi etkili bir \u015fekilde senkronize ederek veri yar\u0131\u015flar\u0131n\u0131 \u00f6nleyebilir ve sisteminizin kararl\u0131l\u0131\u011f\u0131n\u0131 art\u0131rabilirsiniz. Bu rehberde, Go&#039;da semapforun ne oldu\u011funu, neden \u00f6nemli oldu\u011funu ve pratik \u00f6rneklerle nas\u0131l uygulanaca\u011f\u0131n\u0131 ad\u0131m ad\u0131m ke\u015ffedece\u011fiz. Gelin, Go&#039;nun g\u00fc\u00e7l\u00fc e\u015fzamanl\u0131l\u0131k \u00f6zelliklerini semapfor deseniyle nas\u0131l daha verimli kullanabilece\u011finizi birlikte \u00f6\u011frenelim.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/fatihsoysal.com\/blog\/go-ile-eszamanlilik-kontrolu-semapfor-deseni-nasil-kullanilir\/\" \/>\n<meta property=\"og:site_name\" content=\"Kodlar\u0131n Gizemli D\u00fcnyas\u0131\" \/>\n<meta property=\"article:published_time\" content=\"2025-10-10T02:31:42+00:00\" \/>\n<meta name=\"author\" content=\"Fatih Soysal\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Yazan:\" \/>\n\t<meta name=\"twitter:data1\" content=\"Fatih Soysal\" \/>\n\t<meta name=\"twitter:label2\" content=\"Tahmini okuma s\u00fcresi\" \/>\n\t<meta name=\"twitter:data2\" content=\"7 dakika\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/fatihsoysal.com\/blog\/go-ile-eszamanlilik-kontrolu-semapfor-deseni-nasil-kullanilir\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/go-ile-eszamanlilik-kontrolu-semapfor-deseni-nasil-kullanilir\/\"},\"author\":{\"name\":\"Fatih Soysal\",\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1\"},\"headline\":\"Go ile E\u015fzamanl\u0131l\u0131k Kontrol\u00fc: Semapfor Deseni Nas\u0131l Kullan\u0131l\u0131r?\",\"datePublished\":\"2025-10-10T02:31:42+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/go-ile-eszamanlilik-kontrolu-semapfor-deseni-nasil-kullanilir\/\"},\"wordCount\":4854,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1\"},\"inLanguage\":\"tr\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\/\/fatihsoysal.com\/blog\/go-ile-eszamanlilik-kontrolu-semapfor-deseni-nasil-kullanilir\/#respond\"]}],\"copyrightYear\":\"2025\",\"copyrightHolder\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#organization\"}},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/fatihsoysal.com\/blog\/go-ile-eszamanlilik-kontrolu-semapfor-deseni-nasil-kullanilir\/\",\"url\":\"https:\/\/fatihsoysal.com\/blog\/go-ile-eszamanlilik-kontrolu-semapfor-deseni-nasil-kullanilir\/\",\"name\":\"Go ile E\u015fzamanl\u0131l\u0131k Kontrol\u00fc: Semapfor Deseni Nas\u0131l Kullan\u0131l\u0131r?\",\"isPartOf\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#website\"},\"datePublished\":\"2025-10-10T02:31:42+00:00\",\"description\":\"Go programlamada e\u015fzamanl\u0131 kaynak y\u00f6netimi sizi zorluyor mu? Semapfor deseni ile goroutine'lerinizi etkili bir \u015fekilde senkronize ederek veri yar\u0131\u015flar\u0131n\u0131 \u00f6nleyebilir ve sisteminizin kararl\u0131l\u0131\u011f\u0131n\u0131 art\u0131rabilirsiniz. Bu rehberde, Go'da semapforun ne oldu\u011funu, neden \u00f6nemli oldu\u011funu ve pratik \u00f6rneklerle nas\u0131l uygulanaca\u011f\u0131n\u0131 ad\u0131m ad\u0131m ke\u015ffedece\u011fiz. Gelin, Go'nun g\u00fc\u00e7l\u00fc e\u015fzamanl\u0131l\u0131k \u00f6zelliklerini semapfor deseniyle nas\u0131l daha verimli kullanabilece\u011finizi birlikte \u00f6\u011frenelim.\",\"breadcrumb\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/go-ile-eszamanlilik-kontrolu-semapfor-deseni-nasil-kullanilir\/#breadcrumb\"},\"inLanguage\":\"tr\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/fatihsoysal.com\/blog\/go-ile-eszamanlilik-kontrolu-semapfor-deseni-nasil-kullanilir\/\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/fatihsoysal.com\/blog\/go-ile-eszamanlilik-kontrolu-semapfor-deseni-nasil-kullanilir\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Anasayfa\",\"item\":\"https:\/\/fatihsoysal.com\/blog\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Go ile E\u015fzamanl\u0131l\u0131k Kontrol\u00fc: Semapfor Deseni Nas\u0131l Kullan\u0131l\u0131r?\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#website\",\"url\":\"https:\/\/fatihsoysal.com\/blog\/\",\"name\":\"Fatihsoysal.com\",\"description\":\"Blog - Yaz\u0131l\u0131m D\u00fcnyas\u0131 Tecr\u00fcbelerim\",\"publisher\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/fatihsoysal.com\/blog\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"tr\"},{\"@type\":[\"Person\",\"Organization\"],\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1\",\"name\":\"Fatih Soysal\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"tr\",\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/fatihsoysal.com\/blog\/wp-content\/uploads\/2024\/04\/cropped-replicate-prediction-3kgg1hgjn5rgp0cf0p5tr0jw7w-1.png\",\"contentUrl\":\"https:\/\/fatihsoysal.com\/blog\/wp-content\/uploads\/2024\/04\/cropped-replicate-prediction-3kgg1hgjn5rgp0cf0p5tr0jw7w-1.png\",\"width\":512,\"height\":512,\"caption\":\"Fatih Soysal\"},\"logo\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/image\/\"},\"description\":\"Kullan\u0131m ve kodlama m\u00fckemmeliyetini odak alan uygulamalar olu\u015fturma deneyimine sahip, profesyonel olarak 15+ y\u0131l \u00fczeri deneyime sahip bir yaz\u0131l\u0131m m\u00fchendisi.\",\"url\":\"https:\/\/fatihsoysal.com\/blog\/author\/fatihsoysal\/\"}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"Go ile E\u015fzamanl\u0131l\u0131k Kontrol\u00fc: Semapfor Deseni Nas\u0131l Kullan\u0131l\u0131r?","description":"Go programlamada e\u015fzamanl\u0131 kaynak y\u00f6netimi sizi zorluyor mu? Semapfor deseni ile goroutine'lerinizi etkili bir \u015fekilde senkronize ederek veri yar\u0131\u015flar\u0131n\u0131 \u00f6nleyebilir ve sisteminizin kararl\u0131l\u0131\u011f\u0131n\u0131 art\u0131rabilirsiniz. Bu rehberde, Go'da semapforun ne oldu\u011funu, neden \u00f6nemli oldu\u011funu ve pratik \u00f6rneklerle nas\u0131l uygulanaca\u011f\u0131n\u0131 ad\u0131m ad\u0131m ke\u015ffedece\u011fiz. Gelin, Go'nun g\u00fc\u00e7l\u00fc e\u015fzamanl\u0131l\u0131k \u00f6zelliklerini semapfor deseniyle nas\u0131l daha verimli kullanabilece\u011finizi birlikte \u00f6\u011frenelim.","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:\/\/fatihsoysal.com\/blog\/go-ile-eszamanlilik-kontrolu-semapfor-deseni-nasil-kullanilir\/","og_locale":"tr_TR","og_type":"article","og_title":"Go ile E\u015fzamanl\u0131l\u0131k Kontrol\u00fc: Semapfor Deseni Nas\u0131l Kullan\u0131l\u0131r?","og_description":"Go programlamada e\u015fzamanl\u0131 kaynak y\u00f6netimi sizi zorluyor mu? Semapfor deseni ile goroutine'lerinizi etkili bir \u015fekilde senkronize ederek veri yar\u0131\u015flar\u0131n\u0131 \u00f6nleyebilir ve sisteminizin kararl\u0131l\u0131\u011f\u0131n\u0131 art\u0131rabilirsiniz. Bu rehberde, Go'da semapforun ne oldu\u011funu, neden \u00f6nemli oldu\u011funu ve pratik \u00f6rneklerle nas\u0131l uygulanaca\u011f\u0131n\u0131 ad\u0131m ad\u0131m ke\u015ffedece\u011fiz. Gelin, Go'nun g\u00fc\u00e7l\u00fc e\u015fzamanl\u0131l\u0131k \u00f6zelliklerini semapfor deseniyle nas\u0131l daha verimli kullanabilece\u011finizi birlikte \u00f6\u011frenelim.","og_url":"https:\/\/fatihsoysal.com\/blog\/go-ile-eszamanlilik-kontrolu-semapfor-deseni-nasil-kullanilir\/","og_site_name":"Kodlar\u0131n Gizemli D\u00fcnyas\u0131","article_published_time":"2025-10-10T02:31:42+00:00","author":"Fatih Soysal","twitter_card":"summary_large_image","twitter_misc":{"Yazan:":"Fatih Soysal","Tahmini okuma s\u00fcresi":"7 dakika"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/fatihsoysal.com\/blog\/go-ile-eszamanlilik-kontrolu-semapfor-deseni-nasil-kullanilir\/#article","isPartOf":{"@id":"https:\/\/fatihsoysal.com\/blog\/go-ile-eszamanlilik-kontrolu-semapfor-deseni-nasil-kullanilir\/"},"author":{"name":"Fatih Soysal","@id":"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1"},"headline":"Go ile E\u015fzamanl\u0131l\u0131k Kontrol\u00fc: Semapfor Deseni Nas\u0131l Kullan\u0131l\u0131r?","datePublished":"2025-10-10T02:31:42+00:00","mainEntityOfPage":{"@id":"https:\/\/fatihsoysal.com\/blog\/go-ile-eszamanlilik-kontrolu-semapfor-deseni-nasil-kullanilir\/"},"wordCount":4854,"commentCount":0,"publisher":{"@id":"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1"},"inLanguage":"tr","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/fatihsoysal.com\/blog\/go-ile-eszamanlilik-kontrolu-semapfor-deseni-nasil-kullanilir\/#respond"]}],"copyrightYear":"2025","copyrightHolder":{"@id":"https:\/\/fatihsoysal.com\/blog\/#organization"}},{"@type":"WebPage","@id":"https:\/\/fatihsoysal.com\/blog\/go-ile-eszamanlilik-kontrolu-semapfor-deseni-nasil-kullanilir\/","url":"https:\/\/fatihsoysal.com\/blog\/go-ile-eszamanlilik-kontrolu-semapfor-deseni-nasil-kullanilir\/","name":"Go ile E\u015fzamanl\u0131l\u0131k Kontrol\u00fc: Semapfor Deseni Nas\u0131l Kullan\u0131l\u0131r?","isPartOf":{"@id":"https:\/\/fatihsoysal.com\/blog\/#website"},"datePublished":"2025-10-10T02:31:42+00:00","description":"Go programlamada e\u015fzamanl\u0131 kaynak y\u00f6netimi sizi zorluyor mu? Semapfor deseni ile goroutine'lerinizi etkili bir \u015fekilde senkronize ederek veri yar\u0131\u015flar\u0131n\u0131 \u00f6nleyebilir ve sisteminizin kararl\u0131l\u0131\u011f\u0131n\u0131 art\u0131rabilirsiniz. Bu rehberde, Go'da semapforun ne oldu\u011funu, neden \u00f6nemli oldu\u011funu ve pratik \u00f6rneklerle nas\u0131l uygulanaca\u011f\u0131n\u0131 ad\u0131m ad\u0131m ke\u015ffedece\u011fiz. Gelin, Go'nun g\u00fc\u00e7l\u00fc e\u015fzamanl\u0131l\u0131k \u00f6zelliklerini semapfor deseniyle nas\u0131l daha verimli kullanabilece\u011finizi birlikte \u00f6\u011frenelim.","breadcrumb":{"@id":"https:\/\/fatihsoysal.com\/blog\/go-ile-eszamanlilik-kontrolu-semapfor-deseni-nasil-kullanilir\/#breadcrumb"},"inLanguage":"tr","potentialAction":[{"@type":"ReadAction","target":["https:\/\/fatihsoysal.com\/blog\/go-ile-eszamanlilik-kontrolu-semapfor-deseni-nasil-kullanilir\/"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/fatihsoysal.com\/blog\/go-ile-eszamanlilik-kontrolu-semapfor-deseni-nasil-kullanilir\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Anasayfa","item":"https:\/\/fatihsoysal.com\/blog\/"},{"@type":"ListItem","position":2,"name":"Go ile E\u015fzamanl\u0131l\u0131k Kontrol\u00fc: Semapfor Deseni Nas\u0131l Kullan\u0131l\u0131r?"}]},{"@type":"WebSite","@id":"https:\/\/fatihsoysal.com\/blog\/#website","url":"https:\/\/fatihsoysal.com\/blog\/","name":"Fatihsoysal.com","description":"Blog - Yaz\u0131l\u0131m D\u00fcnyas\u0131 Tecr\u00fcbelerim","publisher":{"@id":"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/fatihsoysal.com\/blog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"tr"},{"@type":["Person","Organization"],"@id":"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1","name":"Fatih Soysal","image":{"@type":"ImageObject","inLanguage":"tr","@id":"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/image\/","url":"https:\/\/fatihsoysal.com\/blog\/wp-content\/uploads\/2024\/04\/cropped-replicate-prediction-3kgg1hgjn5rgp0cf0p5tr0jw7w-1.png","contentUrl":"https:\/\/fatihsoysal.com\/blog\/wp-content\/uploads\/2024\/04\/cropped-replicate-prediction-3kgg1hgjn5rgp0cf0p5tr0jw7w-1.png","width":512,"height":512,"caption":"Fatih Soysal"},"logo":{"@id":"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/image\/"},"description":"Kullan\u0131m ve kodlama m\u00fckemmeliyetini odak alan uygulamalar olu\u015fturma deneyimine sahip, profesyonel olarak 15+ y\u0131l \u00fczeri deneyime sahip bir yaz\u0131l\u0131m m\u00fchendisi.","url":"https:\/\/fatihsoysal.com\/blog\/author\/fatihsoysal\/"}]}},"yoast_meta":{"yoast_wpseo_title":"","yoast_wpseo_metadesc":"","yoast_wpseo_canonical":""},"amp_enabled":true,"_links":{"self":[{"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/posts\/31458","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/comments?post=31458"}],"version-history":[{"count":0,"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/posts\/31458\/revisions"}],"wp:attachment":[{"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/media?parent=31458"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/categories?post=31458"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/tags?post=31458"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}