-
Sadrazamv4
instagram:sadrazam.spy Tg:Sadrazamv4
/*
================================================================================
🚀 MODERN ISO C++ PROGRAMLAMA DERSLERİ: BÖLÜM 8 🚀
Eşzamanlılık (Concurrency), std::jthread, Mutex Kilitleri & std::async
================================================================================
GİRİŞ 📌
--------------------------------------------------------------------------------
Yedinci bölümde Lambda ifadelerini, derleyici seviyesindeki Closure yapısını,
C++20 Template Lambdaları ve `std::function` maliyet analizini incelemiştik.
Bu bölümde modern C++'ın en kritik konularından biri olan **Eşzamanlılık (Concurrency)**
ve **Çok İzli Programlama (Multithreading)** mimarisini, ISO C++20 ile gelen
RAII tabanlı `std::jthread` yapısını, veri yarışlarını (Data Race) önleyen kilit
mekanizmalarını (`std::scoped_lock`) ve asenkron görev yönetimini (`std::async`)
ele alacağız.
*/
#include <iostream>
#include <thread>
#include <mutex>
#include <future>
#include <vector>
#include <chrono>
// =============================================================================
// 1. `std::thread` VS ISO C++20 `std::jthread` (RAII & AUTO-JOIN) 🧵
// =============================================================================
/*
* `std::thread` (C++11):
* - Kapsam dışına çıkılmadan önce açıkça `join()` veya `detach()` çağrılmalıdır.
* - Aksi halde yıkıcı (destructor) çalıştığında `std::terminate()` çağrılır ve
* program ÇÖKER!
*
* `std::jthread` (ISO C++20):
* - RAII prensibine tam uyumludur. Yıkıcısı otomatik olarak `join()` yapar.
* - İş parçacığını dışarıdan güvenle durdurmak için `std::stop_token` mekanizmasını
* (Cooperative Cancellation) destekler.
*/
void worker_task(std::stop_token stoken, int id) {
while (!stoken.stop_requested()) {
std::cout << "⚙️ Thread [" << id << "] çalışıyor...\n";
std::this_thread::sleep_for(std::chrono::milliseconds(100));
}
std::cout << "🛑 Thread [" << id << "] durdurma isteği aldı ve sonlandı.\n";
}
void demonstrate_jthread() {
// std::jthread kapsam dışına çıktığında otomatik join olur ve stop_token tetiklenir!
{
std::jthread jt(worker_task, 101);
std::this_thread::sleep_for(std::chrono::milliseconds(350));
// jt.request_stop(); // Yıkıcı otomatik çağıracağı için opsiyoneldir!
}
std::cout << "📌 jthread otomatik olarak katıldı (auto-joined) ve temizlendi.\n";
}
// =============================================================================
// 2. VERİ YARIŞI (DATA RACE) VE `std::scoped_lock` (ISO C++17) 🔒
// =============================================================================
/*
* DATA RACE: İki veya daha fazla iş parçacığı aynı bellek konumuna eşzamanlı
* eriştiğinde ve en az biri YAZMA işlemi yaptığında oluşan tanımsız davranıştır (UB).
*
* DEADLOCK (ÖLÜ DÜĞÜM): İki thread'in birbirinin elindeki kilitleri beklemesi durumu.
*
* ÇÖZÜM: `std::scoped_lock` (ISO C++17)
* Birden fazla Mutex'i ÖLÜ DÜĞÜM OLUŞTURMADAN (Deadlock-free avoidance algorithm)
* RAII yöntemiyle aynı anda kilitler!
*/
struct BankAccount {
std::mutex mtx;
int balance;
explicit BankAccount(int b) : balance(b) {}
};
void transfer(BankAccount& from, BankAccount& to, int amount) {
// ISO C++17: std::scoped_lock birden fazla mutex'i güvenli biçimde kilitler!
std::scoped_lock lock(from.mtx, to.mtx);
if (from.balance >= amount) {
from.balance -= amount;
to.balance += amount;
std::cout << "💸 Transfer Başarılı: " << amount << " TL aktarıldı.\n";
}
}
void demonstrate_data_race_prevention() {
BankAccount acc1(1000);
BankAccount acc2(500);
std::jthread t1(transfer, std::ref(acc1), std::ref(acc2), 200);
std::jthread t2(transfer, std::ref(acc2), std::ref(acc1), 100);
}
// =============================================================================
// 3. ASENKRON GÖREV YÖNETİMİ: `std::async` VE `std::future` ⚡
// =============================================================================
/*
* Thread'leri ve kilitleri manuel yönetmek yerine, değer döndüren arka plan
* görevleri için yüksek seviyeli `std::async` soyutlaması kullanılır.
*
* - `std::launch::async`: Görevin KESİN OLARAK AAYRI BİR THREAD'de çalışacağını garanti eder.
* - `std::future<T>`: Arka plandaki görevin gelecekte üreteceği sonucu temsil eder.
*/
std::uint64_t compute_heavy_task(std::uint32_t val) {
std::this_thread::sleep_for(std::chrono::milliseconds(200));
return static_cast<std::uint64_t>(val) * val;
}
void demonstrate_async_tasks() {
std::cout << "🚀 Asenkron hesaplama başlatılıyor...\n";
// Görevi başka bir thread'e fırlatıyoruz:
std::future<std::uint64_t> fut = std::async(std::launch::async, compute_heavy_task, 5000);
std::cout << "⏳ Ana thread engellenmeden (non-blocking) çalışmaya devam ediyor...\n";
// `get()` çağrısı sonuç hazır olana kadar bloklar (ya da sonucu hemen alır):
std::uint64_t result = fut.get();
std::cout << "🎯 Asenkron Görev Sonucu: " << result << "\n";
}
// =============================================================================
// 4. MAIN VE PROGRAM GİRİŞ NOKTASI 🚀
// =============================================================================
int main() {
std::cout << "============================================" << std::endl;
std::cout << " ISO C++17/20/23 Dersleri - Bolum 8 " << std::endl;
std::cout << "============================================" << std::endl << std::endl;
std::cout << "--- 1. ISO C++20 std::jthread ve Stop Token ---" << std::endl;
demonstrate_jthread();
std::cout << "\n--- 2. Data Race Önleme ve std::scoped_lock ---" << std::endl;
demonstrate_data_race_prevention();
std::cout << "\n--- 3. std::async ve std::future ---" << std::endl;
demonstrate_async_tasks();
std::cout << "\n✔ Bolum 8 Kavramları Başarıyla İşlendi!" << std::endl;
return 0;
}
/*
================================================================================
BÖLÜM ÖZETİ VE GELECEK BÖLÜM 📝
--------------------------------------------------------------------------------
Bu bölümde C++ Concurrency mimarisini, ISO C++20 `std::jthread` yapısını,
`std::scoped_lock` ile kilit yönetimini ve `std::async` ile asenkron görev
yürütmeyi inceledik.
Gelecek Bölüm (Bölüm 9):
- ISO C++20 Coroutines (KORUTİNLER) Mimarısı 🌀
- `co_await`, `co_yield` ve `co_return` Anahtar Kelimeleri
- Promise Object, Coroutine Handle ve Awaitable Interface
- Asenkron Akışlar (Generators) ve Lazily Evaluated Streams Tasarımı
===================
=============================================================
Bölüm 8 Sonu.
================================================================================
*/
================================================================================
🚀 MODERN ISO C++ PROGRAMLAMA DERSLERİ: BÖLÜM 8 🚀
Eşzamanlılık (Concurrency), std::jthread, Mutex Kilitleri & std::async
================================================================================
GİRİŞ 📌
--------------------------------------------------------------------------------
Yedinci bölümde Lambda ifadelerini, derleyici seviyesindeki Closure yapısını,
C++20 Template Lambdaları ve `std::function` maliyet analizini incelemiştik.
Bu bölümde modern C++'ın en kritik konularından biri olan **Eşzamanlılık (Concurrency)**
ve **Çok İzli Programlama (Multithreading)** mimarisini, ISO C++20 ile gelen
RAII tabanlı `std::jthread` yapısını, veri yarışlarını (Data Race) önleyen kilit
mekanizmalarını (`std::scoped_lock`) ve asenkron görev yönetimini (`std::async`)
ele alacağız.
*/
#include <iostream>
#include <thread>
#include <mutex>
#include <future>
#include <vector>
#include <chrono>
// =============================================================================
// 1. `std::thread` VS ISO C++20 `std::jthread` (RAII & AUTO-JOIN) 🧵
// =============================================================================
/*
* `std::thread` (C++11):
* - Kapsam dışına çıkılmadan önce açıkça `join()` veya `detach()` çağrılmalıdır.
* - Aksi halde yıkıcı (destructor) çalıştığında `std::terminate()` çağrılır ve
* program ÇÖKER!
*
* `std::jthread` (ISO C++20):
* - RAII prensibine tam uyumludur. Yıkıcısı otomatik olarak `join()` yapar.
* - İş parçacığını dışarıdan güvenle durdurmak için `std::stop_token` mekanizmasını
* (Cooperative Cancellation) destekler.
*/
void worker_task(std::stop_token stoken, int id) {
while (!stoken.stop_requested()) {
std::cout << "⚙️ Thread [" << id << "] çalışıyor...\n";
std::this_thread::sleep_for(std::chrono::milliseconds(100));
}
std::cout << "🛑 Thread [" << id << "] durdurma isteği aldı ve sonlandı.\n";
}
void demonstrate_jthread() {
// std::jthread kapsam dışına çıktığında otomatik join olur ve stop_token tetiklenir!
{
std::jthread jt(worker_task, 101);
std::this_thread::sleep_for(std::chrono::milliseconds(350));
// jt.request_stop(); // Yıkıcı otomatik çağıracağı için opsiyoneldir!
}
std::cout << "📌 jthread otomatik olarak katıldı (auto-joined) ve temizlendi.\n";
}
// =============================================================================
// 2. VERİ YARIŞI (DATA RACE) VE `std::scoped_lock` (ISO C++17) 🔒
// =============================================================================
/*
* DATA RACE: İki veya daha fazla iş parçacığı aynı bellek konumuna eşzamanlı
* eriştiğinde ve en az biri YAZMA işlemi yaptığında oluşan tanımsız davranıştır (UB).
*
* DEADLOCK (ÖLÜ DÜĞÜM): İki thread'in birbirinin elindeki kilitleri beklemesi durumu.
*
* ÇÖZÜM: `std::scoped_lock` (ISO C++17)
* Birden fazla Mutex'i ÖLÜ DÜĞÜM OLUŞTURMADAN (Deadlock-free avoidance algorithm)
* RAII yöntemiyle aynı anda kilitler!
*/
struct BankAccount {
std::mutex mtx;
int balance;
explicit BankAccount(int b) : balance(b) {}
};
void transfer(BankAccount& from, BankAccount& to, int amount) {
// ISO C++17: std::scoped_lock birden fazla mutex'i güvenli biçimde kilitler!
std::scoped_lock lock(from.mtx, to.mtx);
if (from.balance >= amount) {
from.balance -= amount;
to.balance += amount;
std::cout << "💸 Transfer Başarılı: " << amount << " TL aktarıldı.\n";
}
}
void demonstrate_data_race_prevention() {
BankAccount acc1(1000);
BankAccount acc2(500);
std::jthread t1(transfer, std::ref(acc1), std::ref(acc2), 200);
std::jthread t2(transfer, std::ref(acc2), std::ref(acc1), 100);
}
// =============================================================================
// 3. ASENKRON GÖREV YÖNETİMİ: `std::async` VE `std::future` ⚡
// =============================================================================
/*
* Thread'leri ve kilitleri manuel yönetmek yerine, değer döndüren arka plan
* görevleri için yüksek seviyeli `std::async` soyutlaması kullanılır.
*
* - `std::launch::async`: Görevin KESİN OLARAK AAYRI BİR THREAD'de çalışacağını garanti eder.
* - `std::future<T>`: Arka plandaki görevin gelecekte üreteceği sonucu temsil eder.
*/
std::uint64_t compute_heavy_task(std::uint32_t val) {
std::this_thread::sleep_for(std::chrono::milliseconds(200));
return static_cast<std::uint64_t>(val) * val;
}
void demonstrate_async_tasks() {
std::cout << "🚀 Asenkron hesaplama başlatılıyor...\n";
// Görevi başka bir thread'e fırlatıyoruz:
std::future<std::uint64_t> fut = std::async(std::launch::async, compute_heavy_task, 5000);
std::cout << "⏳ Ana thread engellenmeden (non-blocking) çalışmaya devam ediyor...\n";
// `get()` çağrısı sonuç hazır olana kadar bloklar (ya da sonucu hemen alır):
std::uint64_t result = fut.get();
std::cout << "🎯 Asenkron Görev Sonucu: " << result << "\n";
}
// =============================================================================
// 4. MAIN VE PROGRAM GİRİŞ NOKTASI 🚀
// =============================================================================
int main() {
std::cout << "============================================" << std::endl;
std::cout << " ISO C++17/20/23 Dersleri - Bolum 8 " << std::endl;
std::cout << "============================================" << std::endl << std::endl;
std::cout << "--- 1. ISO C++20 std::jthread ve Stop Token ---" << std::endl;
demonstrate_jthread();
std::cout << "\n--- 2. Data Race Önleme ve std::scoped_lock ---" << std::endl;
demonstrate_data_race_prevention();
std::cout << "\n--- 3. std::async ve std::future ---" << std::endl;
demonstrate_async_tasks();
std::cout << "\n✔ Bolum 8 Kavramları Başarıyla İşlendi!" << std::endl;
return 0;
}
/*
================================================================================
BÖLÜM ÖZETİ VE GELECEK BÖLÜM 📝
--------------------------------------------------------------------------------
Bu bölümde C++ Concurrency mimarisini, ISO C++20 `std::jthread` yapısını,
`std::scoped_lock` ile kilit yönetimini ve `std::async` ile asenkron görev
yürütmeyi inceledik.
Gelecek Bölüm (Bölüm 9):
- ISO C++20 Coroutines (KORUTİNLER) Mimarısı 🌀
- `co_await`, `co_yield` ve `co_return` Anahtar Kelimeleri
- Promise Object, Coroutine Handle ve Awaitable Interface
- Asenkron Akışlar (Generators) ve Lazily Evaluated Streams Tasarımı
===================
=============================================================
Bölüm 8 Sonu.
================================================================================
*/
🔒 Bu içeriği görmek için giriş yapın