成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

一文搞懂Linux線程同步原理

系統 Linux
互斥鎖雖然有很多優點,能夠很方便的進行線程同步,但是互斥鎖是通過futex系統調用實現,采用系統調用必然存在用戶態和內核態的切換問題,如果這種切換很頻繁的話,必然會影響系統性能和降低系統效率,后續我們將繼續探索更為高效的線程同步方式。

大家好,今天和大家聊一聊Linux線程同步相關的知識,線程同步相關的知識值得花時間好好研究,要設計出高性能軟件架構,必須學好Linux線程同步,對Linux線程同步原理有深刻的認知。

1.背景知識

1.1 原子變量和原子操作

原子變量和原子操作是多線程編程中的重要概念,用于保證多線程環境下的數據同步和互斥。原子操作是指不會被線程調度機制打斷的操作,一旦開始就會一直運行到結束,中間不會切換到其他進程。原子變量是原子操作的基本單位。

C11標準引入了原子類型和原子操作,用于在多線程環境下保證數據的同步和一致性。

常見原子變量類型:

圖片圖片

常見原子操作:

圖片圖片

1.2 futex系統調用

futex是Linux內核提供的一種系統調用,用于實現用戶空間線程之間的同步和互斥。它是fast userspace mutex的縮寫,意為快速用戶空間互斥鎖。futex的主要作用是在用戶空間實現鎖和條件變量,避免了用戶空間和內核空間之間的頻繁切換,從而提高了多線程程序的性能。

futex系統調用的基本用法是:

一個線程在需要鎖或等待條件變量時,調用futex系統調用,將自己掛起。

另一個線程在釋放鎖或改變條件變量時,調用futex系統調用,喚醒等待的線程。

1.2.1 futex函數原型

int futex(int *uaddr, int futex_op, int val, const struct timespec *timeout, int *uaddr2, int val3);

功能:futex函數是Linux內核提供的一種輕量級的鎖機制,它可以用于用戶空間進程間的同步。

參數:

uaddr:指向等待的變量的指針。

futex_op:表示要執行的操作,可以是以下值之一:

  • FUTEX_WAIT:等待變量的值變為指定值。
  • FUTEX_WAKE:喚醒等待變量的線程。

val:與操作相關的值。

timeout:超時時間。

uaddr2:第二個等待變量的指針。

val3:與第二個等待變量相關的值。

1.2.2  futex實現原理

圖片圖片

通過futex系統調用執行FUTEX_WAIT命令,可以將線程掛起,futex傳入的uaddr參數會通過hash函數轉換成hash值,通過hash值能索引到futex_hash_bucket,此時會創建futex_q節點,futex_q節點會存儲哈希key,線程相關信息,futex_q節點會插入chain鏈表。

通過futex系統調用執行FUTEX_WAKE命令可喚醒掛起線程,futex系統調用通過uaddr參數找到對應的futex_q節點,然后喚醒futex_q節點指向的掛起線程。

2.線程為什么需要同步?

Linux線程是在Linux操作系統中實現的一種輕量級進程,也稱為輕量級進程或者LWP。同一線程組的線程共享主線程(進程)的地址空間、文件描述符、信號處理等資源。

在Linux中,CPU的調度是以線程為單位進行調度的,因此線程的調度也是以線程為單位進行調度的。

圖片圖片

由于線程之間共享地址空間,文件描述,信號相關資源,所以線程之間必然會存在同時訪問同一資源的問題,如果不進行線程同步,就會導致數據的不一致性和安全性問題。同步可以保證在同一時刻只有一個線程訪問共享資源,從而避免了數據的沖突和錯誤。

3. 互斥鎖實現原理

互斥鎖的實現視基于原子操作和futex系統調用實現。

3.1 互斥鎖常見操作

  • 創建互斥鎖

pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;

  • 加鎖

pthread_mutex_lock(&mutex);

  • 解鎖

pthread_mutex_unlock(&mutex);

  • 嘗試加鎖

pthread_mutex_trylock(&mutex);

  • 銷毀互斥鎖

pthread_mutex_destroy(&mutex);

3.2 互斥鎖實現原理

圖片圖片

互斥鎖本質是一個原子變量,原子變量同樣是一個共享變量,不同的線程都能訪問,只不過原子變量采用的是原子操作,互斥鎖的操作不可被中斷。

1)互斥鎖初始化

將原子變量設置成0,原子變量不同的值代表鎖不同的狀態:

  • 原子變量等于0:互斥鎖空閑,未加鎖。
  • 原子變量等于1:互斥鎖加鎖成功。
  • 原子變量等于2:互斥鎖加鎖失敗,線程通過futex(FUTEX_WAIT)系統調用被掛起。

2)互斥鎖加鎖

  • 通過atomic_compare_exchange_strong(value, 0, 1)原子操作,判斷當前互斥鎖是否已經被加鎖,如果原子變量等于0,說明互斥鎖空閑,此時可以對互斥鎖進行加鎖操作,將原子變量設置為1,返回true。
  • 如果原子變量不等于0,則說明互斥鎖已經加鎖,此時互斥鎖加鎖線程需要通過futex(FUTEX_WAIT)系統調用將線程掛起,掛起之前需要通過atomic_exchange(value, 2)設置原子變量的值為2,并返回舊原子變量值,通過舊原子變量值可以判斷原子變量是否被其他線程操作。

3)互斥鎖解鎖

  • 線程通過atomic_exchange(value, 0)原子操作,將原子變量的值設置成0,返回舊原子變量值。
  • 如果舊原子變量的值等于2,說明有一個線程被掛起,此時需要通過futex(FUTEX_WAKE)系統調用喚醒掛起線程,解鎖成功。
  • 如果舊原子變量小于等于1,則直接解鎖成功。

總結:

互斥鎖雖然有很多優點,能夠很方便的進行線程同步,但是互斥鎖是通過futex系統調用實現,采用系統調用必然存在用戶態和內核態的切換問題,如果這種切換很頻繁的話,必然會影響系統性能和降低系統效率,后續我們將繼續探索更為高效的線程同步方式。

責任編輯:武曉燕 來源: 物聯網心球
相關推薦

2023-09-08 08:20:46

ThreadLoca多線程工具

2025-04-27 10:03:51

2021-07-08 10:08:03

DvaJS前端Dva

2024-07-12 14:46:20

2021-01-13 05:21:59

參數

2020-09-03 06:35:44

Linux權限文件

2023-09-22 10:45:47

云原生云計算

2024-04-12 12:19:08

語言模型AI

2022-03-24 08:51:48

Redis互聯網NoSQL

2022-04-12 09:05:30

Linux時鐘

2022-03-28 19:19:45

Linux時間子系統

2022-04-11 10:56:43

線程安全

2021-03-22 10:05:59

netstat命令Linux

2023-09-15 12:00:01

API應用程序接口

2021-04-27 19:21:48

HBase原理開源

2023-11-03 12:29:48

Java虛擬線程

2019-04-03 09:27:01

MySQLInnoDB務ACID

2020-04-15 16:30:24

掃碼登錄微信前端

2023-09-02 21:27:09

2021-03-04 00:09:31

MySQL體系架構
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 日韩av啪啪网站大全免费观看 | 日韩在线一区二区三区 | 国产精品久久亚洲 | 成人影院午夜 | 五月天婷婷综合 | 国产一区二区免费 | 91精品国产91久久综合桃花 | 成人免费视频 | 女人夜夜春 | 久久久精品综合 | 九九热在线观看 | 欧美日韩在线观看一区二区三区 | 亚洲综合在| 亚洲第1页 | 亚洲36d大奶网 | 日日综合 | 97免费视频在线观看 | 91看片网 | 六月成人网 | 国产精品178页 | 亚洲精品在线免费播放 | 伊人电影院av | 欧美精品在线一区二区三区 | 国产成人精品久久久 | 成人在线a | 国产免费观看一级国产 | 99精品欧美一区二区三区 | 曰批视频在线观看 | 91视频一区二区三区 | 一区二区三区免费 | 国产亚洲一区二区精品 | av中文在线观看 | 蜜桃毛片 | 国产专区视频 | 在线一区| av在线免费看网址 | 亚洲视频一区 | 日韩欧美在线视频 | 亚洲欧美国产毛片在线 | 在线观看成人精品 | 日韩精品一区二区三区四区 |