日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

ios原子操作和各种锁

發布時間:2025/3/14 编程问答 20 豆豆
生活随笔 收集整理的這篇文章主要介紹了 ios原子操作和各种锁 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

iOS多線程編程指南(四)線程同步(2)

2013-07-16 12:13 佚名 dreamingwish?字號:T?|?T

涉及到線程安全時,一個好的設計是最好的保護。避免共享資源,并盡量減少線程間的相互作用,這樣可以讓它們減少互相的干擾。但是一個完全無干擾的設計是不可能的。在線程必須交互的情況下,你需要使用同步工具,來確保當它們交互的時候是安全的。

AD:51CTO學院:IT精品課程在線看!

?

5.使用原子操作

非阻塞同步的方式是用來執行某些類型的操作而避免擴展使用鎖。盡管鎖是同步兩個線程的很好方式,獲取一個鎖是一個很昂貴的操作,即使在無競爭的狀態下。相比,許多原子操作花費很少的時間來完成操作也可以達到和鎖一樣的效果。

原子操作可以讓你在32位或64位的處理器上面執行簡單的數學和邏輯的運算操作。這些操作依賴于特定的硬件設施(和可選的內存屏障)來保證給定的操作在影響內存再次訪問的時候已經完成。在多線程情況下,你應該總是使用原子操作,它和內存屏障組合使用來保證多個線程間正確的同步內存。

表4-3列出了可用的原子運算和本地操作和相應的函數名。這些函數聲明在/usr/include/libkern/OSAtomic.h頭文件里面,在那里你也可以找到完整的語法。這些函數的64-位版本只能在64位的進程里面使用。

Table 4-3??Atomic math and logic operations

Operation

Function name

Description

Add

OSAtomicAdd32
OSAtomicAdd32Barrier
OSAtomicAdd64
OSAtomicAdd64Barrier

Adds two integer values together and stores the result in one of the specified variables.

Increment

OSAtomicIncrement32
OSAtomicIncrement32Barrier
OSAtomicIncrement64
OSAtomicIncrement64Barrier

Increments the specified integer value by 1.

Decrement

OSAtomicDecrement32
OSAtomicDecrement32Barrier
OSAtomicDecrement64
OSAtomicDecrement64Barrier

Decrements the specified integer value by 1.

Logical OR

OSAtomicOr32
OSAtomicOr32Barrier

Performs a logical OR between the specified 32-bit value and a 32-bit mask.

Logical AND

OSAtomicAnd32
OSAtomicAnd32Barrier

Performs a logical AND between the specified 32-bit value and a 32-bit mask.

Logical XOR

OSAtomicXor32
OSAtomicXor32Barrier

Performs a logical XOR between the specified 32-bit value and a 32-bit mask.

Compare and swap

OSAtomicCompareAndSwap32
OSAtomicCompareAndSwap32Barrier
OSAtomicCompareAndSwap64
OSAtomicCompareAndSwap64Barrier
OSAtomicCompareAndSwapPtr
OSAtomicCompareAndSwapPtrBarrier
OSAtomicCompareAndSwapInt
OSAtomicCompareAndSwapIntBarrier
OSAtomicCompareAndSwapLong
OSAtomicCompareAndSwapLongBarrier

Compares a variable against the specified old value. If the two values are equal, this function assigns the specified new value to the variable; otherwise, it does nothing. The comparison and assignment are done as one atomic operation and the function returns a Boolean value indicating whether the swap actually occurred.

Test and set

OSAtomicTestAndSet
OSAtomicTestAndSetBarrier

Tests a bit in the specified variable, sets that bit to 1, and returns the value of the old bit as a Boolean value. Bits are tested according to the formula (0×80 >> (n & 7)) of byte((char*)address + (n >> 3)) where n is the bit number and address is a pointer to the variable. This formula effectively breaks up the variable into 8-bit sized chunks and orders the bits in each chunk in reverse. For example, to test the lowest-order bit (bit 0) of a 32-bit integer, you would actually specify 7 for the bit number; similarly, to test the highest order bit (bit 32), you would specify 24 for the bit number.

Test and clear

OSAtomicTestAndClear
OSAtomicTestAndClearBarrier

Tests a bit in the specified variable, sets that bit to 0, and returns the value of the old bit as a Boolean value. Bits are tested according to the formula (0×80 >> (n & 7)) of byte((char*)address + (n >> 3)) where n is the bit number and address is a pointer to the variable. This formula effectively breaks up the variable into 8-bit sized chunks and orders the bits in each chunk in reverse. For example, to test the lowest-order bit (bit 0) of a 32-bit integer, you would actually specify 7 for the bit number; similarly, to test the highest order bit (bit 32), you would specify 24 for the bit number.

?

大部分原子函數的行為是相對簡單的并應該是你想要的。然而列表4-1顯式了測試-設置和比較-交換操作的原子行為,它們相對復雜一點。OSAtomicTestAndSet 第一次調用展示了如何對一個整形值進行位運算操作,而它的結果和你預期的有差異。最后兩次調用OSAtomicCompareAndSwap32顯式它的行為。所有情況下,這些函數都是無競爭的下調用的,此時沒有其他線程試圖操作這些值。

Listing 4-1??Performing atomic operations

  • int32_t??theValue?=?0;?
  • OSAtomicTestAndSet(0,?&theValue);?
  • //?theValue?is?now?128.?
  • ??
  • theValue?=?0;?
  • OSAtomicTestAndSet(7,?&theValue);?
  • //?theValue?is?now?1.?
  • ??
  • theValue?=?0;?
  • OSAtomicTestAndSet(15,?&theValue)?
  • //?theValue?is?now?256.?
  • ??
  • OSAtomicCompareAndSwap32(256,?512,?&theValue);?
  • //?theValue?is?now?512.?
  • ??
  • OSAtomicCompareAndSwap32(256,?1024,?&theValue);?
  • //?theValue?is?still?512.?
  • 關于原子操作的更多信息,參見atomic的主頁和/usr/include/libkern/OSAtomic.h頭文件。

    6.使用鎖

    鎖是線程編程同步工具的基礎。鎖可以讓你很容易保護代碼中一大塊區域以便你可以確保代碼的正確性。Mac OS X和iOS都位所有類型的應用程序提供了互斥鎖,而Foundation框架定義一些特殊情況下互斥鎖的額外變種。以下個部分顯式了如何使用這些鎖的類型。

    6.1 使用POSIX互斥鎖

    POSIX互斥鎖在很多程序里面很容易使用。為了新建一個互斥鎖,你聲明并初始化一個pthread_mutex_t的結構。為了鎖住和解鎖一個互斥鎖,你可以使用pthread_mutex_lock和pthread_mutex_unlock函數。列表4-2顯式了要初始化并使用一個POSIX線程的互斥鎖的基礎代碼。當你用完一個鎖之后,只要簡單的調用pthread_mutex_destroy來釋放該鎖的數據結構。

    Listing 4-2??Using a mutex lock

  • pthread_mutex_t?mutex;?
  • void?MyInitFunction()?
  • {?
  • ????pthread_mutex_init(&mutex,?NULL);?
  • }?
  • ??
  • void?MyLockingFunction()?
  • {?
  • ????pthread_mutex_lock(&mutex);?
  • ????//?Do?work.?
  • ????pthread_mutex_unlock(&mutex);?
  • }?
  • 注意:上面的代碼只是簡單的顯式了使用一個POSIX線程互斥鎖的步驟。你自己的代碼應該檢查這些函數返回的錯誤碼,并適當的處理它們。

    6.2 使用NSLock類

    在Cocoa程序中NSLock中實現了一個簡單的互斥鎖。所有鎖(包括NSLock)的接口實際上都是通過NSLocking協議定義的,它定義了lock和unlock方法。你使用這些方法來獲取和釋放該鎖。

    除了標準的鎖行為,NSLock類還增加了tryLock和lockBeforeDate:方法。方法tryLock試圖獲取一個鎖,但是如果鎖不可用的時候,它不會阻塞線程。相反,它只是返回NO。而lockBeforeDate:方法試圖獲取一個鎖,但是如果鎖沒有在規定的時間內被獲得,它會讓線程從阻塞狀態變為非阻塞狀態(或者返回NO)。

    下面的例子顯式了你可以是NSLock對象來協助更新一個可視化顯式,它的數據結構被多個線程計算。如果線程沒有立即獲的鎖,它只是簡單的繼續計算直到它可以獲得鎖再更新顯式。?

    6.3 使用@synchronized指令

    @synchronized指令是在Objective-C代碼中創建一個互斥鎖非常方便的方法。@synchronized指令做和其他互斥鎖一樣的工作(它防止不同的線程在同一時間獲取同一個鎖)。然而在這種情況下,你不需要直接創建一個互斥鎖或鎖對象。相反,你只需要簡單的使用Objective-C對象作為鎖的令牌,如下面例子所示:

  • -?(void)myMethod:(id)anObj?
  • {?
  • ????@synchronized(anObj)?
  • ????{?
  • ????????//?Everything?between?the?braces?is?protected?by?the?@synchronized?directive.?
  • ????}?
  • }?
  • 創建給@synchronized指令的對象是一個用來區別保護塊的唯一標示符。如果你在兩個不同的線程里面執行上述方法,每次在一個線程傳遞了一個不同的對象給anObj參數,那么每次都將會擁有它的鎖,并持續處理,中間不被其他線程阻塞。然而,如果你傳遞的是同一個對象,那么多個線程中的一個線程會首先獲得該鎖,而其他線程將會被阻塞直到第一個線程完成它的臨界區。

    作為一種預防措施,@synchronized塊隱式的添加一個異常處理例程來保護代碼。該處理例程會在異常拋出的時候自動的釋放互斥鎖。這意味著為了使用@synchronized指令,你必須在你的代碼中啟用異常處理。了如果你不想讓隱式的異常處理例程帶來額外的開銷,你應該考慮使用鎖的類。

    關于更多@synchronized指令的信息,參閱The Objective-C Programming Language。

    6.4 使用其他Cocoa鎖

    以下個部分描述了使用Cocoa其他類型的鎖。

    使用NSRecursiveLock對象

    NSRecursiveLock類定義的鎖可以在同一線程多次獲得,而不會造成死鎖。一個遞歸鎖會跟蹤它被多少次成功獲得了。每次成功的獲得該鎖都必須平衡調用鎖住和解鎖的操作。只有所有的鎖住和解鎖操作都平衡的時候,鎖才真正被釋放給其他線程獲得。

    正如它名字所言,這種類型的鎖通常被用在一個遞歸函數里面來防止遞歸造成阻塞線程。你可以類似的在非遞歸的情況下使用他來調用函數,這些函數的語義要求它們使用鎖。以下是一個簡單遞歸函數,它在遞歸中獲取鎖。如果你不在該代碼里使用NSRecursiveLock對象,當函數被再次調用的時候線程將會出現死鎖。

  • NSRecursiveLock?*theLock?=?[[NSRecursiveLock?alloc]?init];?
  • void?MyRecursiveFunction(int?value)?
  • {?
  • ????[theLock?lock];?
  • ????if?(value?!=?0)?
  • ????{?
  • ????????--value;?
  • ????????MyRecursiveFunction(value);?
  • ????}?
  • ????[theLock?unlock];?
  • }?
  • MyRecursiveFunction(5);?
  • 注意:因為一個遞歸鎖不會被釋放直到所有鎖的調用平衡使用了解鎖操作,所以你必須仔細權衡是否決定使用鎖對性能的潛在影響。長時間持有一個鎖將會導致其他線程阻塞直到遞歸完成。如果你可以重寫你的代碼來消除遞歸或消除使用一個遞歸鎖,你可能會獲得更好的性能。

    使用NSConditionLock對象

    NSConditionLock對象定義了一個互斥鎖,可以使用特定值來鎖住和解鎖。不要把該類型的鎖和條件(參見“條件”部分)混淆了。它的行為和條件有點類似,但是它們的實現非常不同。

    通常,當多線程需要以特定的順序來執行任務的時候,你可以使用一個NSConditionLock對象,比如當一個線程生產數據,而另外一個線程消費數據。生產者執行時,消費者使用由你程序指定的條件來獲取鎖(條件本身是一個你定義的整形值)。當生產者完成時,它會解鎖該鎖并設置鎖的條件為合適的整形值來喚醒消費者線程,之后消費線程繼續處理數據。

    NSConditionLock的鎖住和解鎖方法可以任意組合使用。比如,你可以使用unlockWithCondition:和lock消息,或使用lockWhenCondition:和unlock消息。當然,后面的組合可以解鎖一個鎖但是可能沒有釋放任何等待某特定條件值的線程。

    下面的例子顯示了生產者-消費者問題如何使用條件鎖來處理。想象一個應用程序包含一個數據的隊列。一個生產者線程把數據添加到隊列,而消費者線程從隊列中取出數據。生產者不需要等待特定的條件,但是它必須等待鎖可用以便它可以安全的把數據添加到隊列。

  • id?condLock?=?[[NSConditionLock?alloc]?initWithCondition:NO_DATA];?
  • ??
  • while(true)?
  • {?
  • ????[condLock?lock];?
  • ????/*?Add?data?to?the?queue.?*/?
  • ????[condLock?unlockWithCondition:HAS_DATA];?
  • }?
  • 因為初始化條件鎖的值為NO_DATA,生產者線程在初始化的時候可以毫無問題的獲取該鎖。它會添加隊列數據,并把條件設置為HAS_DATA。在隨后的迭代中,生產者線程可以把到達的數據添加到隊列,無論隊列是否為空或依然有數據。唯一讓它進入阻塞的情況是當一個消費者線程充隊列取出數據的時候。

    因為消費者線程必須要有數據來處理,它會使用一個特定的條件來等待隊列。當生產者把數據放入隊列時,消費者線程被喚醒并獲取它的鎖。它可以從隊列中取出數據,并更新隊列的狀態。下列代碼顯示了消費者線程處理循環的基本結構。

  • while?(true)?
  • {?
  • ????[condLock?lockWhenCondition:HAS_DATA];?
  • ????/*?Remove?data?from?the?queue.?*/?
  • ????[condLock?unlockWithCondition:(isEmpty???NO_DATA?:?HAS_DATA)];?
  • ??
  • ????//?Process?the?data?locally.?
  • }
  • 使用NSDistributedLock對象

    NSDistributedLock類可以被多臺主機上的多個應用程序使用來限制對某些共享資源的訪問,比如一個文件。鎖本身是一個高效的互斥鎖,它使用文件系統項目來實現,比如一個文件或目錄。對于一個可用的NSDistributedLock對象,鎖必須由所有使用它的程序寫入。這通常意味著把它放在文件系統,該文件系統可以被所有運行在計算機上面的應用程序訪問。

    不像其他類型的鎖,NSDistributedLock并沒有實現NSLocking協議,所有它沒有lock方法。一個lock方法將會阻塞線程的執行,并要求系統以預定的速度輪詢鎖。以其在你的代碼中實現這種約束,NSDistributedLock提供了一個tryLock方法,并讓你決定是否輪詢。

    因為它使用文件系統來實現,一個NSDistributedLock對象不會被釋放除非它的擁有者顯式的釋放它。如果你的程序在用戶一個分布鎖的時候崩潰了,其他客戶端簡無法訪問該受保護的資源。在這種情況下,你可以使用breadLock方法來打破現存的鎖以便你可以獲取它。但是通常應該避免打破鎖,除非你確定擁有進程已經死亡并不可能再釋放該鎖。

    和其他類型的鎖一樣,當你使用NSDistributedLock對象時,你可以通過調用unlock方法來釋放它。

    原文連接:http://mobile.51cto.com/hot-403089_1.htm

    轉載于:https://www.cnblogs.com/wfwenchao/articles/3688231.html

    總結

    以上是生活随笔為你收集整理的ios原子操作和各种锁的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

    主站蜘蛛池模板: 亚洲综合自拍偷拍 | 做暧暧视频在线观看 | 九色porny原创自拍 | 大乳护士喂奶hd | 女人的天堂网 | 欧美女人一区二区 | 欧美狠狠爱 | 国产日韩欧美在线观看视频 | 毛片久久久久久 | 粉嫩在线 | 少妇高潮喷水在线观看 | 18禁男女爽爽爽午夜网站免费 | 黄色激情四射 | 精品久久久久久亚洲综合网站 | 成人免费一区二区三区在线观看 | 好吊色综合 | 国产激情精品一区二区三区 | 四虎永久在线精品免费网址 | 国产精品二区一区二区aⅴ污介绍 | 人妻激情偷乱视频一区二区三区 | 插吧插吧综合网 | 性生交生活片1 | 日本孕妇孕交 | 加勒比hezyo黑人专区 | 国产精品毛片久久久久久久av | 国产精品入口日韩视频大尺度 | 三级视频在线 | 国产欧美精品一区二区 | 男人的天堂伊人 | 精品无人区无码乱码毛片国产 | 天天插视频 | 在线观看免费视频a | 欧美日本在线看 | 丰满人妻一区二区三区性色 | 国产女主播一区二区三区 | 日韩av综合在线 | 操比网站 | 99情趣网 | 国产精品hd | 深夜福利在线播放 | 国产日韩一区 | 婷婷干| 电车痴汉在线观看 | 久久久久久久成人 | 亚洲射吧| 啪啪福利视频 | h网站免费在线观看 | 亚洲小视频在线 | 老牛影视少妇在线观看 | 在线观看欧美一区二区三区 | 国产www免费 | 禁漫天堂在线 | 久草精品在线观看 | 亚洲综合av一区二区三区 | 手机在线看片1024 | 成人污在线观看 | 亚洲国产精品人人爽夜夜爽 | 一区二区三区资源 | 夜夜骑天天操 | 亚洲综合色在线 | 中文字幕av一区二区三区人妻少妇 | 好吊妞视频在线 | 懂色av中文字幕 | 韩国日本在线观看 | 午夜小福利 | 日本在线看片 | 欧美成人三级伦在线观看 | 日本人妻换人妻毛片 | 乱子伦一区二区三区 | 奶水喷溅 在线播放 | 黄色日比视频 | 欧美日韩一区视频 | 日本网站在线免费观看 | 日本肉体xxxx裸体137大胆图 | 操欧美美女 | 国产天堂精品 | 欧美成人性生活视频 | 9l视频自拍九色9l视频 | 亚洲精品aa | 97高清国语自产拍 | 久久偷拍免费视频 | 日韩黄色av | 少妇高潮喷水在线观看 | 国产亚洲精品久久久久四川人 | 亚洲欧美一区二区三区四区五区 | 999视频| 国产ts三人妖大战直男 | 欧美视频在线一区二区三区 | 国产在线久久久 | 美女高潮黄又色高清视频免费 | 亚洲免费在线视频观看 | 久久传媒 | 天天色综合av | 人妻久久一区二区三区 | 青青国产视频 | 老头吃奶性行交 | 一级全黄色片 | 亚洲va在线 | 日韩av中文字幕在线播放 |