{"id":19396,"date":"2017-10-30T15:59:56","date_gmt":"2017-10-30T19:59:56","guid":{"rendered":"https:\/\/mjtsai.com\/blog\/?p=19396"},"modified":"2024-04-30T16:58:00","modified_gmt":"2024-04-30T20:58:00","slug":"locks-thread-safety-and-swift-2017-edition","status":"publish","type":"post","link":"https:\/\/mjtsai.com\/blog\/2017\/10\/30\/locks-thread-safety-and-swift-2017-edition\/","title":{"rendered":"Locks, Thread Safety, and Swift: 2017 Edition"},"content":{"rendered":"<p><a href=\"https:\/\/mikeash.com\/pyblog\/friday-qa-2017-10-27-locks-thread-safety-and-swift-2017-edition.html\">Mike Ash<\/a>:<\/p>\n<blockquote cite=\"https:\/\/mikeash.com\/pyblog\/friday-qa-2017-10-27-locks-thread-safety-and-swift-2017-edition.html\"><p>Note that <code>pthread_mutex_t<\/code>, <code>pthread_rwlock_t<\/code>, and <code>os_unfair_lock<\/code> are value types, not reference types. That means that if you use <code>=<\/code> on them, you make a copy. This is important, because these types can&rsquo;t be copied! If you copy one of the <code>pthread<\/code> types, the copy will be unusable and may crash when you try to use it. The <code>pthread<\/code> functions that work with these types assume that the values are at the same memory addresses as where they were initialized, and putting them somewhere else afterwards is a bad idea. <code>os_unfair_lock<\/code> won&rsquo;t crash, but you get a completely separate lock out of it which is never what you want.<\/p><p>If you use these types, you must be careful never to copy them, whether explicitly with a <code>=<\/code> operator, or implicitly by, for example, embedding them in a <code>struct<\/code> or capturing them in a closure.<\/p><p>Additionally, since locks are inherently mutable objects, this means you need to declare them with <code>var<\/code> instead of <code>let<\/code>.<\/p><p>[&#8230;]<\/p><p>You must be careful with the <code>pthread<\/code> locks, because you can create a value using the empty <code>()<\/code> initializer, but that value won&rsquo;t be a valid lock. These locks must be separately initialized using <code>pthread_mutex_init<\/code> or <code>pthread_rwlock_init<\/code>[&#8230;]<\/p><\/blockquote>\n\n<p>Previously: <a href=\"https:\/\/mjtsai.com\/blog\/2015\/02\/06\/locks-thread-safety-and-swift\/\">Locks, Thread Safety, and Swift<\/a>, <a href=\"https:\/\/mjtsai.com\/blog\/2015\/12\/16\/osspinlock-is-unsafe\/\">OSSpinLock Is Unsafe<\/a>, <a href=\"https:\/\/mjtsai.com\/blog\/2016\/10\/07\/os_unfair_lock\/\">os_unfair_lock<\/a>.<\/p>\n\n<p>Update (2018-07-31): <a href=\"http:\/\/www.vadimbulavin.com\/benchmarking-locking-apis\/\">Vadim Bulavin<\/a> (via <a href=\"https:\/\/www.andybargh.com\/swiftdevelopments-144\">Andy Bargh<\/a>):<\/p>\n<blockquote cite=\"http:\/\/www.vadimbulavin.com\/benchmarking-locking-apis\/\"><p>In this article we will benchmark performance of most notable Apple locking APIs and suggest best options based on their characteristics.<\/p><p>[&#8230;]<\/p><p>Based on the benchmark results, <code>DispatchQueue<\/code> must be your best choice for creating a critical section in your code.<\/p><p>Under 10000 calculations it performs almost identical to locks, while providing higher-level and thus less error-prone API.<\/p><\/blockquote>","protected":false},"excerpt":{"rendered":"<p>Mike Ash: Note that pthread_mutex_t, pthread_rwlock_t, and os_unfair_lock are value types, not reference types. That means that if you use = on them, you make a copy. This is important, because these types can&rsquo;t be copied! If you copy one of the pthread types, the copy will be unusable and may crash when you try [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"apple_news_api_created_at":"2018-07-31T19:31:42Z","apple_news_api_id":"a8b191aa-2896-4152-92f5-c697085a7d7c","apple_news_api_modified_at":"2024-04-30T20:58:05Z","apple_news_api_revision":"AAAAAAAAAAAAAAAAAAAAAA==","apple_news_api_share_url":"https:\/\/apple.news\/AqLGRqiiWQVKS9caXCFp9fA","apple_news_coverimage":0,"apple_news_coverimage_caption":"","apple_news_is_hidden":false,"apple_news_is_paid":false,"apple_news_is_preview":false,"apple_news_is_sponsored":false,"apple_news_maturity_rating":"","apple_news_metadata":"\"\"","apple_news_pullquote":"","apple_news_pullquote_position":"","apple_news_slug":"","apple_news_sections":"\"\"","apple_news_suppress_video_url":false,"apple_news_use_image_component":false,"footnotes":""},"categories":[4],"tags":[800,880,31,1472,1529,138,71,901],"class_list":["post-19396","post","type-post","status-publish","format-standard","hentry","category-programming-category","tag-concurrency","tag-grand-central-dispatch-gcd","tag-ios","tag-ios-11","tag-macos-10-13","tag-optimization","tag-programming","tag-swift-programming-language"],"apple_news_notices":[],"_links":{"self":[{"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/posts\/19396","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/comments?post=19396"}],"version-history":[{"count":3,"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/posts\/19396\/revisions"}],"predecessor-version":[{"id":43022,"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/posts\/19396\/revisions\/43022"}],"wp:attachment":[{"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/media?parent=19396"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/categories?post=19396"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/tags?post=19396"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}