0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫(xiě)文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

如何用C++11實(shí)現(xiàn)自旋鎖

科技綠洲 ? 來(lái)源:Linux開(kāi)發(fā)架構(gòu)之路 ? 作者:Linux開(kāi)發(fā)架構(gòu)之路 ? 2023-11-11 16:48 ? 次閱讀

下面我會(huì)分析一下自旋鎖,并代碼實(shí)現(xiàn)自旋鎖和互斥鎖的性能對(duì)比,以及利用C++11實(shí)現(xiàn)自旋鎖。

一:自旋鎖(spin lock)

自旋鎖是一種用于保護(hù)多線程共享資源的鎖,與一般互斥鎖(mutex)不同之處在于當(dāng)自旋鎖嘗試獲取鎖時(shí)以忙等待(busy waiting)的形式不斷地循環(huán)檢查鎖是否可用。

在多CPU的環(huán)境中, 對(duì)持有鎖較短的程序來(lái)說(shuō),使用自旋鎖代替一般的互斥鎖往往能夠提高程序的性能。

最后加粗的句子很重要,本文將針對(duì)該結(jié)論進(jìn)行驗(yàn)證。

下面是man手冊(cè)中對(duì)自旋鎖pthread_spin_lock()函數(shù)的描述:

DESCRIPTION The pthread_spin_lock() function shall lock the spin lock referenced by lock. The calling thread shall acquire the lock if it is not held by another thread. Otherwise, the thread shall spin (that is, shall not return from the pthread_spin_lock() call) until the lock becomes available. The results are undefined if the calling thread holds the lock at the time the call is made. The pthread_spin_trylock() function shall lock the spin lock referenced by lock if it is not held by any thread. Otherwise, the function shall fail. The results are undefined if any of these functions is called with an uninitialized spin lock.

可以看出,自選鎖的主要特征:當(dāng)自旋鎖被一個(gè)線程獲得時(shí),它不能被其它線程獲得。如果其他線程嘗試去phtread_spin_lock()獲得該鎖,那么它將不會(huì)從該函數(shù)返回,而是一直自旋(spin),直到自旋鎖可用為止。

使用自旋鎖時(shí)要注意:

  • 由于自旋時(shí)不釋放CPU,因而持有自旋鎖的線程應(yīng)該盡快釋放自旋鎖,否則等待該自旋鎖的線程會(huì)一直在哪里自旋,這就會(huì)浪費(fèi)CPU時(shí)間。
  • 持有自旋鎖的線程在sleep之前應(yīng)該釋放自旋鎖以便其他咸亨可以獲得該自旋鎖。內(nèi)核編程中,如果持有自旋鎖的代碼sleep了就可能導(dǎo)致整個(gè)系統(tǒng)掛起。(下面會(huì)解釋)

使用任何鎖都需要消耗系統(tǒng)資源(內(nèi)存資源和CPU時(shí)間),這種資源消耗可以分為兩類:

1.建立鎖所需要的資源

2.當(dāng)線程被阻塞時(shí)所需要的資源

POSIX提供的與自旋鎖相關(guān)的函數(shù)有以下幾個(gè),都在中。

int pthread_spin_init(pthread_spinlock_t *lock, int pshared);

初始化spin lock, 當(dāng)線程使用該函數(shù)初始化一個(gè)未初始化或者被destroy過(guò)的spin lock有效。該函數(shù)會(huì)為spin lock申請(qǐng)資源并且初始化spin lock為unlocked狀態(tài)。

有關(guān)第二個(gè)選項(xiàng)是這么說(shuō)的:

If the Thread Process-Shared Synchronization option is supported and the value of pshared is PTHREAD_PROCESS_SHARED, the implementation shall permit the spin lock to be operated upon by any thread that has access to the memory where the spin lock is allocated, even if it is allocated in memory that is shared by multiple processes. If the Thread Process-Shared Synchronization option is supported and the value of pshared is PTHREAD_PROCESS_PRIVATE, or if the option is not supported, the spin lock shall only be operated upon by threads created within the same process as the thread that initialized the spin lock. If threads of differing processes attempt to operate on such a spin lock, the behav‐ ior is undefined.

所以,如果初始化spin lock的線程設(shè)置第二個(gè)參數(shù)為PTHREAD_PROCESS_SHARED,那么該spin lock不僅被初始化線程所在的進(jìn)程中所有線程看到,而且可以被其他進(jìn)程中的線程看到,PTHREAD_PROESS_PRIVATE則只被同一進(jìn)程中線程看到。如果不設(shè)置該參數(shù),默認(rèn)為后者。

int pthread_spin_destroy(pthread_spinlock_t *lock);

銷毀spin lock,作用和mutex的相關(guān)函數(shù)類似,就不翻譯了:

The pthread_spin_destroy() function shall destroy the spin lock referenced by lock and release any resources used by the lock. The effect of subsequent use of the lock is undefined until the lock is reinitialized by another call to pthread_spin_init(). The results are undefined if pthread_spin_destroy() is called when a thread holds the lock, or if this function is called with an uninitialized thread spin lock.

不過(guò)和mutex的destroy函數(shù)一樣有這樣的性質(zhì)(當(dāng)初害慘了我):

The result of referring to copies of that object in calls to pthread_spin_destroy(), pthread_spin_lock(), pthread_spin_try‐ lock(), or pthread_spin_unlock() is undefined.

int pthread_spin_lock(pthread_spinlock_t *lock);

加鎖函數(shù),功能上文都說(shuō)過(guò)了,不過(guò)這么一點(diǎn)值得注意:

EBUSY A thread currently holds the lock. These functions shall not return an error code of [EINTR].

int pthread_spin_trylock(pthread_spinlock_t *lock);

還有這個(gè)函數(shù),這個(gè)一般很少用到。

int pthread_spin_unlock(pthread_spinlock_t *lock);

解鎖函數(shù)。不是持有鎖的線程調(diào)用或者解鎖一個(gè)沒(méi)有l(wèi)ock的spin lock這樣的行為都是undefined的。

二:自旋鎖和互斥鎖的區(qū)別

從實(shí)現(xiàn)原理上來(lái)講,Mutex屬于sleep-waiting類型的 鎖。例如在一個(gè)雙核的機(jī)器上有兩個(gè)線程(線程A和線程B),它們分別運(yùn)行在Core0和Core1上。假設(shè)線程A想要通過(guò) pthread_mutex_lock操作去得到一個(gè)臨界區(qū)的鎖,而此時(shí)這個(gè)鎖正被線程B所持有,那么線程A就會(huì)被阻塞(blocking),Core0 會(huì)在此時(shí)進(jìn)行上下文切換(Context Switch)將線程A置于等待隊(duì)列中, 此時(shí)Core0就可以運(yùn)行其他的任務(wù)(例如另一個(gè)線程C)而不必進(jìn)行忙等待。而Spin lock則不然,它屬于busy-waiting類型的鎖,如果線程A是使用pthread_spin_lock操作去請(qǐng)求鎖,那么線程A就會(huì)一直在 Core0上進(jìn)行忙等待并不停的進(jìn)行鎖請(qǐng)求,直到得到這個(gè)鎖為止。

如果大家去查閱Linux glibc中對(duì)pthreads API的實(shí)現(xiàn)NPTL(Native POSIX Thread Library) 的源碼的話(使用”getconf GNU_LIBPTHREAD_VERSION”命令可以得到我們系統(tǒng)中NPTL的版本號(hào)),就會(huì)發(fā)現(xiàn)pthread_mutex_lock()操作如果 沒(méi)有鎖成功的話就會(huì)調(diào)用system_wait()的系統(tǒng)調(diào)用并將當(dāng)前線程加入該mutex的等待隊(duì)列里。而spin lock則可以理解為在一個(gè)while(1)循環(huán)中用內(nèi)嵌的匯編代碼實(shí)現(xiàn)的鎖操作(印象中看過(guò)一篇論文介紹說(shuō)在linux內(nèi)核中spin lock操作只需要兩條CPU指令,解鎖操作只用一條指令就可以完成)。有興趣的朋友可以參考另一個(gè)名為sanos的微內(nèi)核中pthreds API的實(shí)現(xiàn):mutex.c spinlock.c,盡管與NPTL中的代碼實(shí)現(xiàn)不盡相同,但是因?yàn)樗膶?shí)現(xiàn)非常簡(jiǎn)單易懂,對(duì)我們理解spin lock和mutex的特性還是很有幫助的。

對(duì)于自旋鎖來(lái)說(shuō),它只需要消耗很少的資源來(lái)建立鎖;隨后當(dāng)線程被阻塞時(shí),它就會(huì)一直重復(fù)檢查看鎖是否可用了,也就是說(shuō)當(dāng)自旋鎖處于等待狀態(tài)時(shí)它會(huì)一直消耗CPU時(shí)間。

對(duì)于互斥鎖來(lái)說(shuō),與自旋鎖相比它需要消耗大量的系統(tǒng)資源來(lái)建立鎖;隨后當(dāng)線程被阻塞時(shí),線程的調(diào)度狀態(tài)被修改,并且線程被加入等待線程隊(duì)列;最后當(dāng)鎖可用 時(shí),在獲取鎖之前,線程會(huì)被從等待隊(duì)列取出并更改其調(diào)度狀態(tài);但是在線程被阻塞期間,它不消耗CPU資源。

因此自旋鎖和互斥鎖適用于不同的場(chǎng)景。自旋鎖適用于那些僅需要阻塞很短時(shí)間的場(chǎng)景,而互斥鎖適用于那些可能會(huì)阻塞很長(zhǎng)時(shí)間的場(chǎng)景。

三:自旋鎖與linux內(nèi)核進(jìn)程調(diào)度關(guān)系

現(xiàn)在我們就來(lái)說(shuō)一說(shuō)之前的問(wèn)題,如果臨界區(qū)可能包含引起睡眠的代碼則不能使用自旋鎖,否則可能引起死鎖:

那么為什么信號(hào)量保護(hù)的代碼可以睡眠而自旋鎖會(huì)死鎖呢?

先看下自旋鎖的實(shí)現(xiàn)方法吧,自旋鎖的基本形式如下:

spin_lock(&mr_lock):

    //critical region

    spin_unlock(&mr_lock);

跟蹤一下spin_lock(&mr_lock)的實(shí)現(xiàn)

#define spin_lock(lock) _spin_lock(lock)

#define _spin_lock(lock) __LOCK(lock)

#define __LOCK(lock)

do { preempt_disable(); __acquire(lock); (void)(lock); } while (0)

注意到“preempt_disable()”,這個(gè)調(diào)用的功能是“關(guān)搶占”(在spin_unlock中會(huì)重新開(kāi)啟搶占功能)。從中可以看出,使用自旋鎖保護(hù)的區(qū)域是工作在非搶占的狀態(tài);即使獲取不到鎖,在“自旋”狀態(tài)也是禁止搶占的。了解到這,我想咱們應(yīng)該能夠理解為何自旋鎖保護(hù) 的代碼不能睡眠了。試想一下,如果在自旋鎖保護(hù)的代碼中間睡眠,此時(shí)發(fā)生進(jìn)程調(diào)度,則可能另外一個(gè)進(jìn)程會(huì)再次調(diào)用spinlock保護(hù)的這段代碼。而我們 現(xiàn)在知道了即使在獲取不到鎖的“自旋”狀態(tài),也是禁止搶占的,而“自旋”又是動(dòng)態(tài)的,不會(huì)再睡眠了,也就是說(shuō)在這個(gè)處理器上不會(huì)再有進(jìn)程調(diào)度發(fā)生了,那么 死鎖自然就發(fā)生了。

總結(jié)下自旋鎖的特點(diǎn):

  • 單CPU非搶占內(nèi)核下:自旋鎖會(huì)在編譯時(shí)被忽略(因?yàn)閱蜟PU且非搶占模式情況下,不可能發(fā)生進(jìn)程切換,時(shí)鐘只有一個(gè)進(jìn)程處于臨界區(qū)(自旋鎖實(shí)際沒(méi)什么用了)
  • 單CPU搶占內(nèi)核下:自選鎖僅僅當(dāng)作一個(gè)設(shè)置搶占的開(kāi)關(guān)(因?yàn)閱蜟PU不可能有并發(fā)訪問(wèn)臨界區(qū)的情況,禁止搶占就可以保證臨街區(qū)唯一被擁有)
  • 多CPU下:此時(shí)才能完全發(fā)揮自旋鎖的作用,自旋鎖在內(nèi)核中主要用來(lái)防止多處理器中并發(fā)訪問(wèn)臨界區(qū),防止內(nèi)核搶占造成的競(jìng)爭(zhēng)。

四:linux發(fā)生搶占的時(shí)間

linux搶占發(fā)生的時(shí)間,搶占分為 用戶搶占和 內(nèi)核搶占。

用戶搶占在以下情況下產(chǎn)生:

  • 從系統(tǒng)調(diào)用返回用戶空間
  • 從中斷處理程序返回用戶空間

內(nèi)核搶占會(huì)發(fā)生在:

  • 當(dāng)從中斷處理程序返回內(nèi)核空間的時(shí)候,且當(dāng)時(shí)內(nèi)核具有可搶占性
  • 當(dāng)內(nèi)核代碼再一次具有可搶占性的時(shí)候(如:spin_unlock時(shí))
  • 如果內(nèi)核中的任務(wù)顯示的調(diào)用schedule() (這個(gè)我暫時(shí)不太懂)

基本的進(jìn)程調(diào)度就是發(fā)生在時(shí)鐘中斷后,并且發(fā)現(xiàn)進(jìn)程的時(shí)間片已經(jīng)使用完了,則發(fā)生進(jìn)程搶占。通常我們會(huì)利用中斷處理程序返回內(nèi)核空間的時(shí)候可進(jìn)行內(nèi)核搶占這個(gè)特性來(lái)提高一些I/O操作的實(shí)時(shí)性,如:當(dāng)I/O事件發(fā)生的時(shí)候,對(duì)應(yīng)的中斷處理程序被激活,當(dāng)它發(fā)現(xiàn)有進(jìn)程在等待這個(gè)I/O事件的時(shí)候,它 會(huì)激活等待進(jìn)程,并且設(shè)置當(dāng)前正在執(zhí)行進(jìn)程的need_resched標(biāo)志,這樣在中斷處理程序返回的時(shí)候,調(diào)度程序被激活,原來(lái)在等待I/O事件的進(jìn)程 (很可能)獲得執(zhí)行權(quán),從而保證了對(duì)I/O事件的相對(duì)快速響應(yīng)(毫秒級(jí))??梢钥闯?,在I/O事件發(fā)生的時(shí)候,I/O事件的處理進(jìn)程會(huì)搶占當(dāng)前進(jìn)程,系統(tǒng) 的響應(yīng)速度與調(diào)度時(shí)間片的長(zhǎng)度無(wú)關(guān)。

五:spin_lock和mutex實(shí)際效率對(duì)比

1.++i是否需要加鎖?

我分別使用POSIX的spin_lock和mutex寫(xiě)了兩個(gè)累加的程序,啟動(dòng)了兩個(gè)線程,并利用時(shí)間戳計(jì)算它們執(zhí)行完累加所用的時(shí)間。

下面這個(gè)是使用spin_lock的代碼,我啟動(dòng)兩個(gè)線程同時(shí)對(duì)num進(jìn)行++,使用spin_lock保護(hù)臨界區(qū),實(shí)際上可能會(huì)有疑問(wèn)++i(++i和++num本文中是一個(gè)意思)為什么還要加鎖?

i++需要加鎖是很明顯的事情,對(duì)i++的操作的印象是,它一般是三步曲,從內(nèi)存中取出i放入寄存器中,在寄存器中對(duì)i執(zhí)行inc操作,然后把i放回內(nèi)存中。這三步明顯是可打斷的,所以需要加鎖。

但是++i可能就有點(diǎn)猶豫了。實(shí)際上印象流是不行的,來(lái)看一下i++和++i的匯編代碼,其實(shí)他們是一樣的,都是三步,我只上一個(gè)圖就行了,如下:

圖片

所以++i也不是原子操作,在多核的機(jī)器上,多個(gè)線程在讀取內(nèi)存中的i時(shí),可能讀取到同一個(gè)值,這就導(dǎo)致多個(gè)線程同時(shí)執(zhí)行+1,但實(shí)際上它們得到的結(jié)果是一樣的,即i只加了一次。還有一點(diǎn):這幾句匯編正說(shuō)明了++i和i++i對(duì)于效率是一樣的,不過(guò)這只是針對(duì)內(nèi)建POD類型而言,如果是class的話,我們都寫(xiě)過(guò)類的++運(yùn)算符的重載,如果一個(gè)類在單個(gè)語(yǔ)句中不寫(xiě)++i,而是寫(xiě)i++的話,那無(wú)疑效率會(huì)有很大的損耗。(有點(diǎn)跑題)

2.spin_lock代碼

首先是spin_lock實(shí)現(xiàn)兩個(gè)線程同時(shí)加一個(gè)數(shù),每個(gè)線程均++num,然后計(jì)算花費(fèi)的時(shí)間。

#include < iostream >
#include < thread >

#include < pthread.h >
#include < sys/time.h >
#include < unistd.h >

int num = 0;
pthread_spinlock_t spin_lock;

int64_t get_current_timestamp()
{
    struct timeval now = {0, 0};
    gettimeofday(&now, NULL);
    return now.tv_sec * 1000 * 1000 + now.tv_usec;
}

void thread_proc()
{
    for(int i=0; i< 100000000; ++i){
        pthread_spin_lock(&spin_lock);
        ++num;
        pthread_spin_unlock(&spin_lock);
    }   
}

int main()
{
    pthread_spin_init(&spin_lock, PTHREAD_PROCESS_PRIVATE);//maybe PHREAD_PROCESS_PRIVATE or PTHREAD_PROCESS_SHARED

    int64_t start = get_current_timestamp();

    std::thread t1(thread_proc), t2(thread_proc);
    t1.join();
    t2.join();

    std::cout< "num:"<

3.mutex代碼

#include < iostream >
#include < thread >

#include < pthread.h >
#include < sys/time.h >
#include < unistd.h >

int num = 0;
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;

int64_t get_current_timestamp()
{   
    struct timeval now = {0, 0}; 
    gettimeofday(&now, NULL);
    return now.tv_sec * 1000 * 1000 + now.tv_usec;
}

void thread_proc()
{
    for(int i=0; i< 1000000; ++i){
        pthread_mutex_lock(&mutex);
        ++num;
        pthread_mutex_unlock(&mutex);
    }   
}

int main()
{
    int64_t start = get_current_timestamp();
   std::thread t1(thread_proc), t2(thread_proc);
    t1.join();
    t2.join();
    std::cout< "num:"<

4.結(jié)果分析

得出的結(jié)果如圖,num是最終結(jié)果,cost是花費(fèi)時(shí)間,單位為us,main2是使用spin lock,

圖片

顯然,在臨界區(qū)只有++num這一條語(yǔ)句的情況下,spin lock相對(duì)花費(fèi)的時(shí)間短一些,實(shí)際上它們有可能接近的情況,取決于CPU的調(diào)度情況,但始終會(huì)是spin lock執(zhí)行的效率在本情況中花費(fèi)時(shí)間更少。

我修改了兩個(gè)程序中臨界區(qū)的代碼,改為:

for(int i=0; i< 1000000; ++i){
        pthread_spin_lock(&spin_lock);
        ++num;
        for(int i=0; i< 100; ++i){
            //do nothing
        }   
        pthread_spin_unlock(&spin_lock);
    }

另一個(gè)使用mutex的程序也加了這么一段,然后結(jié)果就與之前的情況大相徑庭了:

圖片

實(shí)驗(yàn)結(jié)果是如此的明顯,僅僅是在臨界區(qū)內(nèi)加了一個(gè)10圈的循環(huán),spin lock就需要花費(fèi)比mutex更長(zhǎng)的時(shí)間了。

所以, spin lock雖然lock/unlock的性能更好(花費(fèi)很少的CPU指令),但是它只適應(yīng)于臨界區(qū)運(yùn)行時(shí)間很短的場(chǎng)景。實(shí)際開(kāi)發(fā)中,程序員如果對(duì)自己程序的鎖行為不是很了解,否則使用spin lock不是一個(gè)好主意。更保險(xiǎn)的方法是使用mutex,如果對(duì)性能有進(jìn)一步的要求,那么再考慮spin lock。

六:使用C++實(shí)現(xiàn)自主實(shí)現(xiàn)自旋鎖

由于前面原理已經(jīng)很清楚了,現(xiàn)在直接給代碼如下:

#pragma once

#include < atomic >

class spin_lock {
private:
    std::atomic< bool > flag = ATOMIC_VAR_INIT(false);
public:
    spin_lock() = default;
    spin_lock(const spin_lock&) = delete;
    spin_lock& operator=(const spin_lock) = delete;
    void lock(){   //acquire spin lock
        bool expected = false;
        while(!flag.compare_exchange_strong(expected, true));
            expected = false;    
    }   
    void unlock(){   //release spin lock
        flag.store(false);
    }   
};

測(cè)試文件,僅給出關(guān)鍵部分:

int num = 0;
spin_lock sm; 

void thread_proc()
{
    for(int i=0; i< 10000000; ++i){
        sm.lock();
        ++num;
        sm.unlock();
    }   
}

好的,對(duì)自旋鎖的總結(jié)就先到這里了。

聲明:本文內(nèi)容及配圖由入駐作者撰寫(xiě)或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場(chǎng)。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問(wèn)題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • 多線程
    +關(guān)注

    關(guān)注

    0

    文章

    277

    瀏覽量

    19897
  • 函數(shù)
    +關(guān)注

    關(guān)注

    3

    文章

    4277

    瀏覽量

    62323
  • C++
    C++
    +關(guān)注

    關(guān)注

    21

    文章

    2100

    瀏覽量

    73453
  • 自旋鎖
    +關(guān)注

    關(guān)注

    0

    文章

    11

    瀏覽量

    1574
收藏 人收藏

    評(píng)論

    相關(guān)推薦

    深度解析自旋自旋實(shí)現(xiàn)方案

    入場(chǎng)券自旋和MCS自旋都屬于排隊(duì)自旋(queued spinlock),進(jìn)程按照申請(qǐng)
    發(fā)表于 09-19 11:39 ?4352次閱讀
    深度解析<b class='flag-5'>自旋</b><b class='flag-5'>鎖</b>及<b class='flag-5'>自旋</b><b class='flag-5'>鎖</b>的<b class='flag-5'>實(shí)現(xiàn)</b>方案

    使用C++11新特性實(shí)現(xiàn)一個(gè)通用的線程池設(shè)計(jì)

    C++11標(biāo)準(zhǔn)之前,多線程編程只能使用pthread_xxx開(kāi)頭的一組POSIX標(biāo)準(zhǔn)的接口。從C++11標(biāo)準(zhǔn)開(kāi)始,多線程相關(guān)接口封裝在了C++的std命名空間里。
    的頭像 發(fā)表于 12-22 13:58 ?1127次閱讀
    使用<b class='flag-5'>C++11</b>新特性<b class='flag-5'>實(shí)現(xiàn)</b>一個(gè)通用的線程池設(shè)計(jì)

    Linux驅(qū)動(dòng)開(kāi)發(fā)筆記-自旋和信號(hào)量

    !案例:利用自旋實(shí)現(xiàn)一個(gè)設(shè)備只能被一個(gè)應(yīng)用程序所打開(kāi)測(cè)試步驟:同整型原子變量的實(shí)驗(yàn)步驟www.arm8.net 嵌入式論壇信號(hào)量:1.信號(hào)量對(duì)應(yīng)的數(shù)據(jù)結(jié)構(gòu):struct semaphore2.信號(hào)量如何使用呢
    發(fā)表于 08-30 18:08

    Linux內(nèi)核同步機(jī)制的自旋原理是什么?

    自旋是專為防止多處理器并發(fā)而引入的一種,它在內(nèi)核中大量應(yīng)用于中斷處理等部分(對(duì)于單處理器來(lái)說(shuō),防止中斷處理中的并發(fā)可簡(jiǎn)單采用關(guān)閉中斷的方式,即在標(biāo)志寄存器中關(guān)閉/打開(kāi)中斷標(biāo)志位,不需要自旋
    發(fā)表于 03-31 08:06

    怎么在atmega128中實(shí)現(xiàn)自旋

    什么是自旋?有哪些缺陷?怎么在atmega128中實(shí)現(xiàn)自旋?
    發(fā)表于 01-24 06:54

    《深入理解C++11C++11新特性解析與應(yīng)用的詳細(xì)電子教材免費(fèi)下載

    國(guó)內(nèi)首本全面深入解讀 C++11 新標(biāo)準(zhǔn)的專著,由 C++ 標(biāo)準(zhǔn)委員會(huì)代表和 IBM XL 編譯器中國(guó)開(kāi)發(fā)團(tuán)隊(duì)共同撰寫(xiě)。不僅詳細(xì)闡述了 C++11 標(biāo)準(zhǔn)的設(shè)計(jì)原則,而且系統(tǒng)地講解了 C++11
    發(fā)表于 08-27 08:00 ?0次下載

    信號(hào)量和自旋

    。??? Linux 使用的同步機(jī)制可以說(shuō)從2.0到2.6以來(lái)不斷發(fā)展完善。從最初的原子操作,到后來(lái)的信號(hào)量,從大內(nèi)核到今天的自旋。這些同步機(jī)制的發(fā)展伴隨 Linux從單處理器到對(duì)稱多處理器的過(guò)度
    發(fā)表于 04-02 14:43 ?795次閱讀

    自旋的發(fā)展歷史與使用方法

    自旋是Linux內(nèi)核里最常用的之一,自旋的概念很簡(jiǎn)單,就是如果加鎖失敗在等時(shí)是使用休眠等
    的頭像 發(fā)表于 08-08 08:51 ?1665次閱讀

    使用Linux自旋實(shí)現(xiàn)互斥點(diǎn)燈

    自旋最多只能被一個(gè)可執(zhí)行線程持有。如果一個(gè)線程試圖獲得一個(gè)已經(jīng)被持有的自旋,那么該線程將循環(huán)等待,然后不斷的判斷是否能夠被成功獲取,直
    的頭像 發(fā)表于 04-13 15:09 ?747次閱讀
    使用Linux<b class='flag-5'>自旋</b><b class='flag-5'>鎖</b><b class='flag-5'>實(shí)現(xiàn)</b>互斥點(diǎn)燈

    C++11新的類功能(特殊成員函數(shù)、override和final)

    C++11在原有的4個(gè)特殊成員函數(shù)(默認(rèn)構(gòu)造函數(shù)、復(fù)制構(gòu)造函數(shù)、復(fù)制賦值運(yùn)算符和析構(gòu)函數(shù))的基礎(chǔ)上新增了移動(dòng)構(gòu)造函數(shù)和移動(dòng)賦值運(yùn)算符。
    的頭像 發(fā)表于 07-18 16:02 ?461次閱讀

    自旋和互斥的區(qū)別有哪些

    自旋 自旋與互斥很相似,在訪問(wèn)共享資源之前對(duì)自旋
    的頭像 發(fā)表于 07-21 11:19 ?9330次閱讀

    基于C++11的線程池實(shí)現(xiàn)

    C++11 加入了線程庫(kù),從此告別了標(biāo)準(zhǔn)庫(kù)不支持并發(fā)的歷史。然而 c++ 對(duì)于多線程的支持還是比較低級(jí),稍微高級(jí)一點(diǎn)的用法都需要自己去實(shí)現(xiàn),譬如線程池、信號(hào)量等。 線程池(thread pool
    的頭像 發(fā)表于 11-13 15:29 ?706次閱讀

    互斥自旋的區(qū)別 自旋臨界區(qū)可以被中斷嗎?

    互斥自旋的區(qū)別 自旋臨界區(qū)可以被中斷嗎? 互斥
    的頭像 發(fā)表于 11-22 17:41 ?735次閱讀

    自旋和互斥的使用場(chǎng)景是什么

    自旋和互斥是兩種常見(jiàn)的同步機(jī)制,它們?cè)诙嗑€程編程中被廣泛使用。在本文中,我們將介紹自旋和互斥
    的頭像 發(fā)表于 07-10 10:05 ?848次閱讀

    互斥自旋實(shí)現(xiàn)原理

    互斥自旋是操作系統(tǒng)中常用的同步機(jī)制,用于控制對(duì)共享資源的訪問(wèn),以避免多個(gè)線程或進(jìn)程同時(shí)訪問(wèn)同一資源,從而引發(fā)數(shù)據(jù)不一致或競(jìng)爭(zhēng)條件等問(wèn)題。 互斥(Mutex) 互斥
    的頭像 發(fā)表于 07-10 10:07 ?388次閱讀