自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

一文搞懂Linux線程同步原理

系統(tǒng) Linux
互斥鎖雖然有很多優(yōu)點(diǎn),能夠很方便的進(jìn)行線程同步,但是互斥鎖是通過futex系統(tǒng)調(diào)用實(shí)現(xiàn),采用系統(tǒng)調(diào)用必然存在用戶態(tài)和內(nèi)核態(tài)的切換問題,如果這種切換很頻繁的話,必然會(huì)影響系統(tǒng)性能和降低系統(tǒng)效率,后續(xù)我們將繼續(xù)探索更為高效的線程同步方式。

大家好,今天和大家聊一聊Linux線程同步相關(guān)的知識(shí),線程同步相關(guān)的知識(shí)值得花時(shí)間好好研究,要設(shè)計(jì)出高性能軟件架構(gòu),必須學(xué)好Linux線程同步,對(duì)Linux線程同步原理有深刻的認(rèn)知。

1.背景知識(shí)

1.1 原子變量和原子操作

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

C11標(biāo)準(zhǔn)引入了原子類型和原子操作,用于在多線程環(huán)境下保證數(shù)據(jù)的同步和一致性。

常見原子變量類型:

圖片圖片

常見原子操作:

圖片圖片

1.2 futex系統(tǒng)調(diào)用

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

futex系統(tǒng)調(diào)用的基本用法是:

一個(gè)線程在需要鎖或等待條件變量時(shí),調(diào)用futex系統(tǒng)調(diào)用,將自己掛起。

另一個(gè)線程在釋放鎖或改變條件變量時(shí),調(diào)用futex系統(tǒng)調(diào)用,喚醒等待的線程。

1.2.1 futex函數(shù)原型

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

功能:futex函數(shù)是Linux內(nèi)核提供的一種輕量級(jí)的鎖機(jī)制,它可以用于用戶空間進(jìn)程間的同步。

參數(shù):

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

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

  • FUTEX_WAIT:等待變量的值變?yōu)橹付ㄖ怠?/li>
  • FUTEX_WAKE:喚醒等待變量的線程。

val:與操作相關(guān)的值。

timeout:超時(shí)時(shí)間。

uaddr2:第二個(gè)等待變量的指針。

val3:與第二個(gè)等待變量相關(guān)的值。

1.2.2  futex實(shí)現(xiàn)原理

圖片圖片

通過futex系統(tǒng)調(diào)用執(zhí)行FUTEX_WAIT命令,可以將線程掛起,futex傳入的uaddr參數(shù)會(huì)通過hash函數(shù)轉(zhuǎn)換成hash值,通過hash值能索引到futex_hash_bucket,此時(shí)會(huì)創(chuàng)建futex_q節(jié)點(diǎn),futex_q節(jié)點(diǎn)會(huì)存儲(chǔ)哈希key,線程相關(guān)信息,futex_q節(jié)點(diǎn)會(huì)插入chain鏈表。

通過futex系統(tǒng)調(diào)用執(zhí)行FUTEX_WAKE命令可喚醒掛起線程,futex系統(tǒng)調(diào)用通過uaddr參數(shù)找到對(duì)應(yīng)的futex_q節(jié)點(diǎn),然后喚醒futex_q節(jié)點(diǎn)指向的掛起線程。

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

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

在Linux中,CPU的調(diào)度是以線程為單位進(jìn)行調(diào)度的,因此線程的調(diào)度也是以線程為單位進(jìn)行調(diào)度的。

圖片圖片

由于線程之間共享地址空間,文件描述,信號(hào)相關(guān)資源,所以線程之間必然會(huì)存在同時(shí)訪問同一資源的問題,如果不進(jìn)行線程同步,就會(huì)導(dǎo)致數(shù)據(jù)的不一致性和安全性問題。同步可以保證在同一時(shí)刻只有一個(gè)線程訪問共享資源,從而避免了數(shù)據(jù)的沖突和錯(cuò)誤。

3. 互斥鎖實(shí)現(xiàn)原理

互斥鎖的實(shí)現(xiàn)視基于原子操作和futex系統(tǒng)調(diào)用實(shí)現(xiàn)。

3.1 互斥鎖常見操作

  • 創(chuàng)建互斥鎖

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 互斥鎖實(shí)現(xiàn)原理

圖片圖片

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

1)互斥鎖初始化

將原子變量設(shè)置成0,原子變量不同的值代表鎖不同的狀態(tài):

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

2)互斥鎖加鎖

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

3)互斥鎖解鎖

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

總結(jié):

互斥鎖雖然有很多優(yōu)點(diǎn),能夠很方便的進(jìn)行線程同步,但是互斥鎖是通過futex系統(tǒng)調(diào)用實(shí)現(xiàn),采用系統(tǒng)調(diào)用必然存在用戶態(tài)和內(nèi)核態(tài)的切換問題,如果這種切換很頻繁的話,必然會(huì)影響系統(tǒng)性能和降低系統(tǒng)效率,后續(xù)我們將繼續(xù)探索更為高效的線程同步方式。

責(zé)任編輯:武曉燕 來源: 物聯(lián)網(wǎng)心球
相關(guān)推薦

2023-09-08 08:20:46

ThreadLoca多線程工具

2025-04-27 10:03:51

2021-01-13 05:21:59

參數(shù)

2024-07-12 14:46:20

2021-07-08 10:08:03

DvaJS前端Dva

2023-09-22 10:45:47

云原生云計(jì)算

2020-09-03 06:35:44

Linux權(quán)限文件

2024-04-12 12:19:08

語言模型AI

2022-04-11 10:56:43

線程安全

2022-04-12 09:05:30

Linux時(shí)鐘

2022-03-28 19:19:45

Linux時(shí)間子系統(tǒng)

2022-03-24 08:51:48

Redis互聯(lián)網(wǎng)NoSQL

2023-11-03 12:29:48

Java虛擬線程

2021-04-27 19:21:48

HBase原理開源

2021-03-22 10:05:59

netstat命令Linux

2023-09-15 12:00:01

API應(yīng)用程序接口

2020-04-15 16:30:24

掃碼登錄微信前端

2019-04-03 09:27:01

MySQLInnoDB務(wù)ACID

2021-06-30 08:45:02

內(nèi)存管理面試

2022-08-15 15:39:23

JavaScript面向?qū)ο?/a>數(shù)據(jù)
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)