亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

C++高性能服務(wù)器框架之線程模塊

 更新時(shí)間:2023年06月08日 09:04:41   作者:找人找不到北  
該模塊基于pthread實(shí)現(xiàn),sylar說(shuō),由于c++11中的thread也是由pthread封裝實(shí)現(xiàn)的,并且沒(méi)有提供讀寫(xiě)互斥量,讀寫(xiě)鎖,自旋鎖等,所以自己封裝了pthread,本文主要詳細(xì)介紹了C++高性能服務(wù)器框架中的線程模塊,需要的朋友可以參考下

線程模塊概述

該模塊基于pthread實(shí)現(xiàn)。sylar說(shuō),由于c++11中的thread也是由pthread封裝實(shí)現(xiàn)的,并且沒(méi)有提供讀寫(xiě)互斥量,讀寫(xiě)鎖,自旋鎖等,所以自己封裝了pthread。

鎖模塊實(shí)現(xiàn)了信號(hào)量、互斥量、讀寫(xiě)鎖、自旋鎖、原子鎖的封裝

  • class Semaphore:信號(hào)量封裝
  • class Mutex:互斥量封裝
  • class RWMutex:讀寫(xiě)鎖封裝
  • class Spinlock:自旋鎖封裝
  • class CASLock:原子鎖封裝

線程模塊主要由Thread類實(shí)現(xiàn)

  • class Thread:實(shí)現(xiàn)線程的封裝

關(guān)于線程id的問(wèn)題,在獲取線程id時(shí)使用syscall獲得唯一的線程id

進(jìn)程pid: getpid() ? ? ? ? ? ? ? ? 
線程tid: pthread_self() ? ? //進(jìn)程內(nèi)唯一,但是在不同進(jìn)程則不唯一。
線程pid: syscall(SYS_gettid) ? ? //系統(tǒng)內(nèi)是唯一的

鎖模塊詳解

class Semaphore(信號(hào)量)

mumber(成員函數(shù))

// 信號(hào)量,它本質(zhì)上是一個(gè)長(zhǎng)整型的數(shù)
sem_t m_semaphore;

Semaphore(構(gòu)造函數(shù))

初始化信號(hào)量。函數(shù)原型:int sem_init(sem_t *sem, int pshared, unsigned int value);

其中,參數(shù) sem 是指向要初始化的信號(hào)量的指針;參數(shù) pshared 指定了信號(hào)量是進(jìn)程內(nèi)共享還是跨進(jìn)程共享,如果值為 0,則表示進(jìn)程內(nèi)共享;參數(shù) value 是信號(hào)量的初始值。該函數(shù)成功時(shí)返回 0,否則返回 -1,并設(shè)置適當(dāng)?shù)腻e(cuò)誤碼。

Semaphore::Semaphore(uint32_t count) {
 ? ?if (sem_init(&m_semaphore, 0, count)) {
 ? ? ? ?throw std::logic_error("sem_init error");
 ?  }
}

~Semaphore(析構(gòu)函數(shù))

銷毀信號(hào)量。函數(shù)原型:int sem_destroy(sem_t *sem);

注意,只有在確保沒(méi)有任何線程或進(jìn)程正在使用該信號(hào)量時(shí),才應(yīng)該調(diào)用 sem_destroy() 函數(shù)。否則,可能會(huì)導(dǎo)致未定義的行為。此外,如果在調(diào)用 sem_destroy() 函數(shù)之前,沒(méi)有使用 sem_post() 函數(shù)將信號(hào)量的值增加到其初始值,則可能會(huì)導(dǎo)致在銷毀信號(hào)量時(shí)出現(xiàn)死鎖情況。

Semaphore::~Semaphore() {
 ? ?sem_destroy(&m_semaphore);
}

wait(獲取信號(hào)量)

函數(shù)原型:int sem_wait(sem_t *sem);

其中,參數(shù) sem 是指向要獲取的信號(hào)量的指針。如果在調(diào)用此函數(shù)時(shí)信號(hào)量的值大于零,則該值將遞減并立即返回。如果信號(hào)量的值為零,則當(dāng)前線程將被阻塞,直到信號(hào)量的值大于零或者被信號(hào)中斷。

當(dāng)線程成功獲取信號(hào)量時(shí),可以執(zhí)行相應(yīng)的操作來(lái)使用資源。使用完資源后,可以通過(guò)調(diào)用 sem_post() 函數(shù)來(lái)增加信號(hào)量的值以釋放資源,并使其他等待線程得以繼續(xù)執(zhí)行。

void Semaphore::wait() {
 ? ?if (sem_wait(&m_semaphore)) {
 ? ? ? ?throw std::logic_error("sem_wait error");
 ?  }
}

notify(釋放信號(hào)量

函數(shù)原型:int sem_post(sem_t *sem);用于向指定的命名或未命名信號(hào)量發(fā)送信號(hào),使其計(jì)數(shù)器加1。如果有進(jìn)程或線程正在等待該信號(hào)量,那么其中一個(gè)將被喚醒以繼續(xù)執(zhí)行。

參數(shù):sem:指向要增加計(jì)數(shù)器的信號(hào)量的指針。

返回值:成功時(shí)返回0,失敗時(shí)返回-1,并設(shè)置errno來(lái)指示錯(cuò)誤原因。

void Semaphore::notify() {
 ? ?if (sem_post(&m_semaphore)) {
 ? ? ? ?throw std::logic_error("sem_post error");
 ?  }
}

為方便封裝各種鎖,這里定義了3個(gè)結(jié)構(gòu)體,都在構(gòu)造函數(shù)時(shí)自動(dòng)lock,在析構(gòu)時(shí)自動(dòng)unlock,這樣可以簡(jiǎn)化鎖的操作,避免忘記解鎖導(dǎo)致死鎖。

  • ScopedLockImpl:用來(lái)分裝互斥量,自旋鎖,原子鎖
  • ReadScopedLockImpl && WriteScopedLockImpl:用來(lái)封裝讀寫(xiě)鎖

class Mutex(互斥量)

mumber(成員函數(shù))

// 互斥量
pthread_mutex_t m_mutex;

Mutex(構(gòu)造函數(shù))

初始化互斥鎖對(duì)象。函數(shù)原型:int pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t *attr);

參數(shù)說(shuō)明:

  • mutex:指向要初始化的互斥鎖對(duì)象的指針。
  • attr:指向互斥鎖屬性對(duì)象的指針,可以為NULL以使用默認(rèn)屬性。

返回值:

  • 成功時(shí)返回0,失敗時(shí)返回錯(cuò)誤碼并設(shè)置errno變量。
Mutex () {
    pthread_mutex_init(&m_mutex, nullptr);
}

~Mutex(析構(gòu)函數(shù))

銷毀已初始化的互斥鎖對(duì)象。函數(shù)原型:int pthread_mutex_destroy(pthread_mutex_t *mutex);

參數(shù)說(shuō)明:

  • mutex:指向要銷毀的互斥鎖對(duì)象的指針。

返回值:

  • 成功時(shí)返回0,失敗時(shí)返回錯(cuò)誤碼并設(shè)置errno變量。
~Mutex () {
    pthread_mutex_destroy(&m_mutex);
}

lock(加鎖)

函數(shù)原型:int pthread_mutex_lock(pthread_mutex_t *mutex);

參數(shù)說(shuō)明:

  • mutex:指向要加鎖的互斥鎖對(duì)象的指針。

返回值

  • 成功時(shí)返回0,失敗時(shí)返回錯(cuò)誤碼并設(shè)置errno變量。

當(dāng)一個(gè)線程調(diào)用pthread_mutex_lock()時(shí),如果當(dāng)前該互斥鎖沒(méi)有被其它線程持有,則該線程會(huì)獲得該互斥鎖,并將其標(biāo)記為已被持有;如果該互斥鎖已經(jīng)被其它線程持有,則當(dāng)前線程會(huì)被阻塞,直到該互斥鎖被釋放并重新嘗試加鎖。

void lock() {
    pthread_mutex_lock(&m_mutex);
}

unlock(解鎖)

函數(shù)原型:int pthread_mutex_unlock(pthread_mutex_t *mutex);

參數(shù)說(shuō)明:

  • mutex:指向要解鎖的互斥鎖對(duì)象的指針。

返回值:

  • 成功時(shí)返回0,失敗時(shí)返回錯(cuò)誤碼并設(shè)置errno變量。

當(dāng)一個(gè)線程調(diào)用pthread_mutex_unlock()時(shí),該互斥鎖將被標(biāo)記為未被持有,并且如果有其它線程正在等待該鎖,則其中一個(gè)線程將被喚醒以繼續(xù)執(zhí)行。

void unlock() {
        pthread_mutex_unlock(&m_mutex);
    }

class RWMutex(讀寫(xiě)鎖)

mumber(成員變量)

// 讀寫(xiě)鎖
pthread_rwlock_t m_lock;

RWMutex(構(gòu)造函數(shù))

初始化一個(gè)讀寫(xiě)鎖對(duì)象。函數(shù)原型:int pthread_rwlock_init(pthread_rwlock_t *rwlock, const pthread_rwlockattr_t *attr);

參數(shù)說(shuō)明:

  • rwlock:指向要初始化的讀寫(xiě)鎖對(duì)象的指針。
  • attr:指向讀寫(xiě)鎖屬性對(duì)象的指針,可以為NULL以使用默認(rèn)屬性。

返回值:

  • 成功時(shí)返回0,失敗時(shí)返回錯(cuò)誤碼并設(shè)置errno變量。

讀寫(xiě)鎖是一種同步機(jī)制,用于在多線程環(huán)境下對(duì)共享資源進(jìn)行訪問(wèn)控制。與互斥鎖不同,讀寫(xiě)鎖允許多個(gè)線程同時(shí)讀取共享資源,但只允許一個(gè)線程寫(xiě)入共享資源。這樣可以提高程序的性能和效率,但需要注意避免讀寫(xiě)鎖死鎖等問(wèn)題。

RWMutex() {
    pthread_rwlock_init(&m_lock, nullptr);
}

~RWMutex(析構(gòu)函數(shù))

銷毀一個(gè)讀寫(xiě)鎖。

~RWMutex() {
    pthread_rwlock_destroy(&m_lock);
}

rdlock(加讀鎖)

pthread_rwlock_rdlock()用于獲取讀取鎖(pthread_rwlock_t)上的共享讀取訪問(wèn)權(quán)限。它允許多個(gè)線程同時(shí)讀取共享資源,但不能寫(xiě)入它。如果有線程已經(jīng)持有寫(xiě)入鎖,則其他線程將被阻塞直到寫(xiě)入鎖被釋放。調(diào)用此函數(shù)時(shí),如果另一個(gè)線程已經(jīng)持有寫(xiě)入鎖,則該線程將被阻塞,直到寫(xiě)入鎖被釋放。

void rdlock() {
    pthread_rwlock_rdlock(&m_lock);
}

wrlock(加寫(xiě)鎖)

pthread_rwlock_wrlock()用于獲取寫(xiě)入鎖(pthread_rwlock_t)上的排他寫(xiě)訪問(wèn)權(quán)限。它阻止其他線程讀取或?qū)懭牍蚕碣Y源,直到該線程釋放寫(xiě)入鎖。如果有其他線程已經(jīng)持有讀取或?qū)懭腈i,則調(diào)用此函數(shù)的線程將被阻塞,直到所有的讀取和寫(xiě)入鎖都被釋放。

void wrlock() {
    pthread_rwlock_wrlock(&m_lock);
}

unlock(解鎖)

pthread_rwlock_unlock()用于釋放讀取或?qū)懭腈i(pthread_rwlock_t)。它允許其他線程獲取相應(yīng)的鎖來(lái)訪問(wèn)共享資源。如果當(dāng)前線程沒(méi)有持有讀取或?qū)懭腈i,則調(diào)用pthread_rwlock_unlock將導(dǎo)致未定義的行為。此外,如果已經(jīng)銷毀了讀寫(xiě)鎖,則再次調(diào)用pthread_rwlock_unlock也會(huì)導(dǎo)致未定義的行為。在使用pthread_rwlock_t時(shí),需要注意正確地獲取和釋放讀取或?qū)懭腈i,以確保多個(gè)線程可以正確地訪問(wèn)共享資源。

void unlock() {
    pthread_rwlock_unlock(&m_lock);
}

class Spinlock(自旋鎖)

與mutex不同,自旋鎖不會(huì)使線程進(jìn)入睡眠狀態(tài),而是在獲取鎖時(shí)進(jìn)行忙等待,直到鎖可用。當(dāng)鎖被釋放時(shí),等待獲取鎖的線程將立即獲取鎖,從而避免了線程進(jìn)入和退出睡眠狀態(tài)的額外開(kāi)銷。

mumber(成員變量)

// 自旋鎖
pthread_spinlock_t m_mutex;

Spinlock(構(gòu)造函數(shù))

函數(shù)pthread_spin_init(&m_mutex, 0)是用于對(duì)自旋鎖進(jìn)行初始化的函數(shù),其中第一個(gè)參數(shù)&m_mutex表示要初始化的自旋鎖變量,第二個(gè)參數(shù)0表示使用默認(rèn)的屬性。在調(diào)用pthread_spin_init函數(shù)之前,必須先分配內(nèi)存空間來(lái)存儲(chǔ)自旋鎖變量。與pthread_rwlock_t類似,需要在使用自旋鎖前先進(jìn)行初始化才能正確使用。

Spinlock() {
    pthread_spin_init(&m_mutex, 0);
}

~Spinlock(析構(gòu)函數(shù))

pthread_spin_destroy()用于銷毀自旋鎖(pthread_spinlock_t)。在不再需要自旋鎖時(shí),可以使用pthread_spin_destroy函數(shù)將其銷毀。該函數(shù)確保在銷毀自旋鎖之前所有等待的線程都被解除阻塞并返回適當(dāng)?shù)腻e(cuò)誤碼。如果自旋鎖已經(jīng)被銷毀,則再次調(diào)用pthread_spin_destroy將導(dǎo)致未定義的行為。

~Spinlock() {
    pthread_spin_destroy(&m_mutex);
}

lock(加鎖)

pthread_spin_lock()用于獲取自旋鎖(pthread_spinlock_t)上的排他訪問(wèn)權(quán)限。與mutex不同,自旋鎖在獲取鎖時(shí)忙等待,即不斷地檢查鎖狀態(tài)是否可用,如果不可用則一直循環(huán)等待,直到鎖可用。當(dāng)鎖被其他線程持有時(shí),調(diào)用pthread_spin_lock()的線程將在自旋等待中消耗CPU時(shí)間,直到鎖被釋放并獲取到鎖。

void lock() { pthread_spin_lock(&m_mutex); }

unlock(解鎖)

pthread_spin_unlock()用于釋放自旋鎖(pthread_spinlock_t)。調(diào)用該函數(shù)可以使其他線程獲取相應(yīng)的鎖來(lái)訪問(wèn)共享資源。與mutex不同,自旋鎖在釋放鎖時(shí)并不會(huì)導(dǎo)致線程進(jìn)入睡眠狀態(tài),而是立即釋放鎖并允許等待獲取鎖的線程快速地獲取鎖來(lái)訪問(wèn)共享資源,從而避免了線程進(jìn)入和退出睡眠狀態(tài)的額外開(kāi)銷。

void unlock() {
    pthread_spin_unlock(&m_mutex);
}

class CASLock(原子鎖)

mumber(成員變量)

// m_mutex是一個(gè)原子布爾類型,具有特殊的原子性質(zhì),可以用于實(shí)現(xiàn)線程間同步和互斥。
// volatile關(guān)鍵字表示該變量可能會(huì)被異步修改,因此編譯器不會(huì)對(duì)其進(jìn)行優(yōu)化,而是每次都從內(nèi)存中讀取該變量的值。
volatile std::atomic_flag m_mutex;

CASLock(構(gòu)造函數(shù))

atomic_flag.clear()是C++標(biāo)準(zhǔn)庫(kù)中的一個(gè)原子操作函數(shù),用于將給定的原子標(biāo)志位(atomic flag)清除或重置為未設(shè)置狀態(tài)。

在多線程編程中,原子標(biāo)志位通常用于實(shí)現(xiàn)簡(jiǎn)單的鎖機(jī)制,以確保對(duì)共享資源的訪問(wèn)是互斥的。使用atomic_flag.clear()可以輕松地重置標(biāo)志位,使之再次可用于控制對(duì)共享資源的訪問(wèn)。需要注意的是,由于該函數(shù)是一個(gè)原子操作,因此可以安全地在多個(gè)線程之間使用,而無(wú)需擔(dān)心競(jìng)態(tài)條件和數(shù)據(jù)競(jìng)爭(zhēng)等問(wèn)題。

CASLock () {
    m_mutex.clear(); 
}

lock(加鎖)

std::atomic_flag_test_and_set_explicit()是C++標(biāo)準(zhǔn)庫(kù)中的一個(gè)原子操作函數(shù),用于測(cè)試給定的原子標(biāo)志位(atomic flag)是否被設(shè)置,并在測(cè)試后將其設(shè)置為已設(shè)置狀態(tài)。該函數(shù)接受一個(gè)指向原子標(biāo)志位對(duì)象的指針作為參數(shù),并返回一個(gè)布爾值,表示在調(diào)用函數(shù)前該標(biāo)志位是否已經(jīng)被設(shè)置。第二個(gè)可選參數(shù)order用于指定內(nèi)存序,以控制原子操作的內(nèi)存順序和同步行為。通過(guò)循環(huán)等待實(shí)現(xiàn)了互斥鎖的效果。

std::memory_order_acquire是C++中的一種內(nèi)存序,用于指定原子操作的同步和內(nèi)存順序。具體來(lái)說(shuō),使用std::memory_order_acquire可以確保在當(dāng)前線程獲取鎖之前,所有該線程之前發(fā)生的寫(xiě)操作都被完全同步到主內(nèi)存中。這樣可以防止編譯器或硬件對(duì)寫(xiě)操作進(jìn)行重排序或延遲,從而確保其他線程可以正確地讀取共享資源的最新值。

void lock() {
    while (std::atomic_flag_test_and_set_explicit(&m_mutex, std::memory_order_acquire));
}

unlock(解鎖)

atomic_flag_clear_explicit()是C++標(biāo)準(zhǔn)庫(kù)中的一個(gè)原子操作函數(shù),用于將給定的原子標(biāo)志位(atomic flag)清除或重置為未設(shè)置狀態(tài)。該函數(shù)接受一個(gè)指向原子標(biāo)志位對(duì)象的指針作為參數(shù),并使用可選的第二個(gè)參數(shù)order來(lái)指定內(nèi)存序,以控制原子操作的同步和內(nèi)存順序。

void unlock() {
    std::atomic_flag_clear_explicit(&m_mutex, std::memory_order_release);
}

線程模塊詳解

class Thread

定義了兩個(gè)線程局部變量用于指向當(dāng)前線程以及線程的名稱。

static thread_local是C++中的一個(gè)關(guān)鍵字組合,用于定義靜態(tài)線程本地存儲(chǔ)變量。具體來(lái)說(shuō),當(dāng)一個(gè)變量被聲明為static thread_local時(shí),它會(huì)在每個(gè)線程中擁有自己獨(dú)立的靜態(tài)實(shí)例,并且對(duì)其他線程不可見(jiàn)。這使得變量可以跨越多個(gè)函數(shù)調(diào)用和代碼塊,在整個(gè)程序運(yùn)行期間保持其狀態(tài)和值不變。

需要注意的是,由于靜態(tài)線程本地存儲(chǔ)變量是線程特定的,因此它們的初始化和銷毀時(shí)機(jī)也與普通靜態(tài)變量不同。具體來(lái)說(shuō),在每個(gè)線程首次訪問(wèn)該變量時(shí)會(huì)進(jìn)行初始化,在線程結(jié)束時(shí)才會(huì)進(jìn)行銷毀,而不是在程序啟動(dòng)或運(yùn)行期間進(jìn)行一次性初始化或銷毀。

// 指向當(dāng)前線程 
static thread_local Thread *t_thread = nullptr;
// 指向線程名稱
static thread_local std::string t_thread_name = "UNKNOW";

mumber(成員變量)

// 指向當(dāng)前線程 
static thread_local Thread *t_thread = nullptr;
// 指向線程名稱
static thread_local std::string t_thread_name = "UNKNOW";

Thread(構(gòu)造函數(shù))

初始化線程執(zhí)行函數(shù)、線程名稱,創(chuàng)建新線程。

函數(shù)原型:int pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine) (void *), void *arg);

該函數(shù)接受四個(gè)參數(shù):

  • thread:指向pthread_t類型的指針,用于返回新線程的ID。
  • attr:指向pthread_attr_t類型的指針,該結(jié)構(gòu)體包含一些有關(guān)新線程屬性的信息??梢詫⑵湓O(shè)置為NULL以使用默認(rèn)值。
  • start_routine:是指向新線程函數(shù)的指針,該函數(shù)將在新線程中運(yùn)行。該函數(shù)必須采用一個(gè)void類型的指針作為參數(shù),并返回一個(gè)void類型的指針。
  • arg:是指向新線程函數(shù)的參數(shù)的指針。如果不需要傳遞參數(shù),則可以將其設(shè)置為NULL。

調(diào)用pthread_create函數(shù)后,將會(huì)創(chuàng)建一個(gè)新線程,并開(kāi)始執(zhí)行通過(guò)start_routine傳遞給它的函數(shù)。新線程的ID將存儲(chǔ)在thread指向的變量中。請(qǐng)注意,新線程將在與調(diào)用pthread_create函數(shù)的線程并發(fā)執(zhí)行的情況下運(yùn)行。

Thread::Thread(std::function<void()> cb, const std::string &name)
    :m_cb(cb)
    ,m_name(name) {
    if (m_name.empty()) {
        m_name = "UNKNOW";
    }
    // 創(chuàng)建新線程,并將其與Thread::run方法關(guān)聯(lián),創(chuàng)建的新線程對(duì)象this作為參數(shù)傳給run方法
    int rt = pthread_create(&m_thread, nullptr, &Thread::run, this);
    if (rt) {
        SYLAR_LOG_ERROR(g_logger) << "pthread_creat thread fail, rt = " << rt
                                  << "name = " << name;
        throw std::logic_error("pthread_creat error");
    }
    // 在出構(gòu)造函數(shù)之前,確保線程先跑起來(lái), 保證能夠初始化id
    m_semaphore.wait();
}

~Thread(析構(gòu)函數(shù))

首先檢查m_thread是否存在,如果存在,則調(diào)用pthread_detach(m_thread)函數(shù)來(lái)分離已經(jīng)結(jié)束的線程。pthread_detach函數(shù)用于釋放與線程關(guān)聯(lián)的資源,并確保線程可以安全地終止。通過(guò)在析構(gòu)函數(shù)中分離線程,可以避免在主線程退出時(shí)出現(xiàn)懸掛線程,從而防止內(nèi)存泄漏和其他問(wèn)題。

Thread::~Thread() {
    if (m_thread) {
        pthread_detach(m_thread);
    }
}

join(等待線程執(zhí)行完成)

pthread_join用于等待指定線程的終止,并獲取該線程的返回值。它的原型為:

#include <pthread.h>
int pthread_join(pthread_t thread, void **retval);

該函數(shù)接受兩個(gè)參數(shù):

  • thread:要等待的線程ID。
  • retval:指向指針的指針,用于存儲(chǔ)線程返回的值。如果不需要獲取返回值,則可以將其設(shè)置為NULL。

當(dāng)調(diào)用 pthread_join() 時(shí),當(dāng)前線程會(huì)阻塞,直到指定的線程完成執(zhí)行。一旦線程結(jié)束,當(dāng)前線程就會(huì)恢復(fù)執(zhí)行,并且可以通過(guò) retval 參數(shù)來(lái)獲取線程的返回值。如果不關(guān)心線程的返回值,也可以將 retval 參數(shù)設(shè)置為 NULL。成功:返回 0 表示線程成功退出。

總之,pthread_join函數(shù)是一種阻塞機(jī)制,用于等待指定線程的終止并獲取其返回值,同時(shí)負(fù)責(zé)回收線程所使用的資源。

void Thread::join() {
    if (m_thread) {
        int rt = pthread_join(m_thread, nullptr);
        if (rt) {
            SYLAR_LOG_ERROR(g_logger) << "pthread_join thread fail, rt = " << rt
                                    << "name = " << m_name;
            throw std::logic_error("pthread_join error");
        }
        m_thread = 0;
    }
}

run(線程執(zhí)行函數(shù))

通過(guò)信號(hào)量,能夠確保構(gòu)造函數(shù)在創(chuàng)建線程之后會(huì)一直阻塞,直到run方法運(yùn)行并通知信號(hào)量,構(gòu)造函數(shù)才會(huì)返回。

在構(gòu)造函數(shù)中完成線程的啟動(dòng)和初始化操作,可能會(huì)導(dǎo)致線程還沒(méi)有完全啟動(dòng)就被調(diào)用,從而導(dǎo)致一些未知的問(wèn)題。因此,在出構(gòu)造函數(shù)之前,確保線程先跑起來(lái),保證能夠初始化id,可以避免這種情況的發(fā)生。同時(shí),這也可以保證線程的安全性和穩(wěn)定性。

總結(jié)

  • 對(duì)日志系統(tǒng)的臨界資源進(jìn)行互斥訪問(wèn)時(shí),使用自旋鎖而不是互斥鎖。
  • mutex使用系統(tǒng)調(diào)用將線程阻塞,并等待其他線程釋放鎖后再喚醒它,這種方式適用于長(zhǎng)時(shí)間持有鎖的情況。而spinlock在獲取鎖時(shí)忙等待,即不斷地檢查鎖狀態(tài)是否可用,如果不可用則一直循環(huán)等待,因此適用于短時(shí)間持有鎖的情況。
  • 由于mutex會(huì)將線程阻塞,因此在高并發(fā)情況下可能會(huì)出現(xiàn)線程頻繁地進(jìn)入和退出睡眠狀態(tài),導(dǎo)致系統(tǒng)開(kāi)銷大。而spinlock雖然不會(huì)使線程進(jìn)入睡眠狀態(tài),但會(huì)消耗大量的CPU時(shí)間,在高并發(fā)情況下也容易導(dǎo)致性能問(wèn)題。
  • 另外,當(dāng)一個(gè)線程嘗試獲取已經(jīng)被其他線程持有的鎖時(shí),mutex會(huì)將該線程阻塞,而spinlock則會(huì)在自旋等待中消耗CPU時(shí)間。如果鎖的持有時(shí)間較短,則spinlock比mutex更適合使用;如果鎖的持有時(shí)間較長(zhǎng),則mutex比spinlock
  • 在構(gòu)造函數(shù)中創(chuàng)建子進(jìn)程并等待其完成執(zhí)行是一種常見(jiàn)的技術(shù),可以通過(guò)信號(hào)量(Semaphore)來(lái)實(shí)現(xiàn)主線程等待子線程完成。
  • 首先,在主線程中創(chuàng)建一個(gè)Semaphore對(duì)象并初始化為0。然后,在構(gòu)造函數(shù)中創(chuàng)建子線程,并將Semaphore對(duì)象傳遞給子線程。子線程將執(zhí)行所需的操作,并在最后使用Semaphore對(duì)象發(fā)出信號(hào)通知主線程它已經(jīng)完成了工作。
  • 主線程在構(gòu)造函數(shù)中調(diào)用Semaphore對(duì)象的wait方法,這會(huì)使主線程阻塞直到收到信號(hào)并且Semaphore對(duì)象的計(jì)數(shù)器值大于0。當(dāng)子線程發(fā)出信號(hào)時(shí),Semaphore對(duì)象的計(jì)數(shù)器值增加1,因此主線程可以繼續(xù)執(zhí)行構(gòu)造函數(shù)的剩余部分。

以上就是C++高性能服務(wù)器框架之線程模塊的詳細(xì)內(nèi)容,更多關(guān)于C++ 線程模塊的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • C++之WSAAsyncSelect模型實(shí)例

    C++之WSAAsyncSelect模型實(shí)例

    這篇文章主要介紹了C++的WSAAsyncSelect模型,實(shí)例講述了socket與Windows消息機(jī)制的用法,需要的朋友可以參考下
    2014-10-10
  • 詳解C語(yǔ)言如何執(zhí)行HTTP GET請(qǐng)求

    詳解C語(yǔ)言如何執(zhí)行HTTP GET請(qǐng)求

    在現(xiàn)代互聯(lián)網(wǎng)時(shí)代,網(wǎng)絡(luò)數(shù)據(jù)的獲取和分析變得越來(lái)越重要,本文我們將使用C語(yǔ)言和libcurl庫(kù)來(lái)編寫(xiě)一個(gè)簡(jiǎn)單的網(wǎng)絡(luò)爬蟲(chóng),以執(zhí)行HTTP GET請(qǐng)求并獲取淘寶網(wǎng)頁(yè)的內(nèi)容,感興趣的可以了解下
    2023-11-11
  • C語(yǔ)言結(jié)構(gòu)體struct詳解

    C語(yǔ)言結(jié)構(gòu)體struct詳解

    C語(yǔ)言中,結(jié)構(gòu)體類型屬于一種構(gòu)造類型(其他的構(gòu)造類型還有:數(shù)組類型,聯(lián)合類型),下面這篇文章主要給大家介紹了關(guān)于C語(yǔ)言結(jié)構(gòu)體(struct)的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2022-09-09
  • C++繼承類成員訪問(wèn)權(quán)限修飾符詳解

    C++繼承類成員訪問(wèn)權(quán)限修飾符詳解

    這篇文章主要為大家介紹了C++繼承類成員訪問(wèn)權(quán)限修飾符,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來(lái)幫助
    2021-12-12
  • VS2019安裝配置MFC(安裝vs2019時(shí)沒(méi)有安裝mfc)

    VS2019安裝配置MFC(安裝vs2019時(shí)沒(méi)有安裝mfc)

    這篇文章主要介紹了VS2019安裝配置MFC(安裝vs2019時(shí)沒(méi)有安裝mfc),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2020-03-03
  • C語(yǔ)言實(shí)現(xiàn)文件內(nèi)容的加密與解密

    C語(yǔ)言實(shí)現(xiàn)文件內(nèi)容的加密與解密

    文件內(nèi)容需要加密與解密功能的原因主要有兩個(gè)方面:保護(hù)數(shù)據(jù)安全和確保數(shù)據(jù)完整性,所以接下來(lái)小編就給大家介紹一下如何通過(guò)C語(yǔ)言實(shí)現(xiàn)文件內(nèi)容加密與解密,需要的朋友可以參考下
    2023-08-08
  • 詳解進(jìn)程同步與互斥機(jī)制

    詳解進(jìn)程同步與互斥機(jī)制

    進(jìn)程同步是一個(gè)操作系統(tǒng)級(jí)別的概念,是在多道程序的環(huán)境下,存在著不同的制約關(guān)系,為了協(xié)調(diào)這種互相制約的關(guān)系,實(shí)現(xiàn)資源共享和進(jìn)程協(xié)作,從而避免進(jìn)程之間的沖突,引入了進(jìn)程同步
    2021-06-06
  • 詳解C/C++中const關(guān)鍵字的用法及其與宏常量的比較

    詳解C/C++中const關(guān)鍵字的用法及其與宏常量的比較

    簡(jiǎn)單的說(shuō)const關(guān)鍵字修飾的變量具有常屬性,也就是說(shuō)它所修飾的變量不能被修改,下文給大家介紹C/C++中const關(guān)鍵字的用法及其與宏常量的比較,需要的朋友可以參考下
    2017-07-07
  • C語(yǔ)言 字符串首字母轉(zhuǎn)換成大寫(xiě)簡(jiǎn)單實(shí)例

    C語(yǔ)言 字符串首字母轉(zhuǎn)換成大寫(xiě)簡(jiǎn)單實(shí)例

    這篇文章主要介紹了C語(yǔ)言 字符串首字母轉(zhuǎn)換成大寫(xiě)簡(jiǎn)單實(shí)例的相關(guān)資料,需要的朋友可以參考下
    2017-05-05
  • c++快速排序詳解

    c++快速排序詳解

    快速排序總體思想:先找到一個(gè)樞軸,讓他作為分水嶺,通過(guò)一趟排序?qū)⒋判虻挠涗浄指畛蓛刹糠?前面一部分都比樞軸小,后面一部分樞軸大,然后又分別對(duì)這兩部分記錄繼續(xù)進(jìn)行遞歸的排序,達(dá)到整個(gè)序列有序的目的
    2017-05-05

最新評(píng)論