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

linux多線程編程----信號量的使用

系統(tǒng) Linux
信號是E.W.Dijkstra在二十世紀六十年代末設(shè)計的一種編程架構(gòu)。Dijkstra的模型與鐵路操作有關(guān):假設(shè)某段鐵路是單線的,因此一次只允許一列火車通過。信號將用于同步通過該軌道的火車。

信號是E.W.Dijkstra在二十世紀六十年代末設(shè)計的一種編程架構(gòu)。Dijkstra的模型與鐵路操作有關(guān):假設(shè)某段鐵路是單線的,因此一次只允許一列火車通過。信號將用于同步通過該軌道的火車?;疖囋谶M入單一軌道之前必須等待信號燈變?yōu)樵试S通行的狀態(tài)。火車進入軌道后,會改變信號狀態(tài),防止其他火車進入該軌道?;疖囯x開這段軌道時,必須再次更改信號的狀態(tài),以便允許其他火車進入軌道。在計算機版本中,信號以簡單整數(shù)來表示。線程等待獲得許可以便繼續(xù)運行,然后發(fā)出信號,表示該線程已經(jīng)通過針對信號執(zhí)行P操作來繼續(xù)運行。線程必須等到信號的值為正,然后才能通過將信號值減1來更改該值。完成此操作后,線程會執(zhí)行V操作,即通過將信號值加1來更改該值。這些操作必須以原子方式執(zhí)行,不能再將其劃分成子操作,即,在這些子操作之間不能對信號執(zhí)行其他操作。在P操作中,信號值在減小之前必須為正,從而確保生成的信號值不為負,并且比該值減小之前小1。在P和V操作中,必須在沒有干擾的情況下進行運算。如果針對同一信號同時執(zhí)行兩個V操作,則實際結(jié)果是信號的新值比原來大2。對于大多數(shù)人來說,如同記住Dijkstra是荷蘭人一樣,記住P和V本身的含義并不重要。但是,真正學術(shù)的角度來說,P代表prolagen,這是由proberen te verlagen演變而來的杜撰詞,其意思是嘗試減小。V代表verhogen,其意思是增加。Dijkstra的技術(shù)說明EWD74中介紹了這些含義。sem_wait(3RT)和sem_post(3RT)分別與Dijkstra的P和V操作相對應。sem_trywait(3RT)是P操作的一種條件形式。如果調(diào)用線程不等待就不能減小信號的值,則該調(diào)用會立即返回一個非零值。有兩種基本信號:二進制信號和計數(shù)信號量。二進制信號的值只能是0或1,計數(shù)信號量可

以是任意非負值。二進制信號在邏輯上相當于一個互斥鎖。

不過,盡管不會強制,但互斥鎖應當僅由持有該鎖的線程來解除鎖定。因為不存在“持有信號的線程”這一概念,所以,任何線程都可以執(zhí)行V或sem_post(3RT)操作。計數(shù)信號量與互斥鎖一起使用時的功能幾乎與條件變量一樣強大。在許多情況下,使用計數(shù)信號量實現(xiàn)的代碼比使用條件變量實現(xiàn)的代碼更為簡單。但是,將互斥鎖用于條件變量時,會存在一個隱含的括號。該括號可以清楚表明程序受保護的部分。對于信號則不必如此,可以使用并發(fā)編程當中的go to對其進行調(diào)用。信號的功能強大,但是容易以非結(jié)構(gòu)化的不確定方式使用。

1 命名信號量和未命名信號量

POSIX信號可以是未命名的,也可以是命名的。未命名信號在進程內(nèi)存中分配,并會進行初始化。未命名信號可能可供多個進程使用,具體取決于信號的分配和初始化的方式。未命名信號可以是通過fork()繼承的專用信號,也可以通過用來分配和映射這些信號的常規(guī)文件的訪問保護功能對其進行保護。命名信號類似于進程共享的信號,區(qū)別在于命名信號是使用路徑名而非pshared值引用的。命名信號可以由多個進程共享。命名信號具有屬主用戶ID、組ID和保護模式。對于open、retrieve、close和remove命名信號,可以使用以下函數(shù):sem_open、sem_getvalue、sem_close和sem_unlink。通過使用sem_open,可以創(chuàng)建一個命名信號,其名稱是在文件系統(tǒng)的名稱空間中定義的。

2 計數(shù)信號量概述

從概念上來說,信號量是一個非負整數(shù)計數(shù)。信號量通常用來協(xié)調(diào)對資源的訪問,其中信號計數(shù)會初始化為可用資源的數(shù)目。然后,線程在資源增加時會增加計數(shù),在刪除資源時會減小計數(shù),這些操作都以原子方式執(zhí)行。如果信號計數(shù)變?yōu)榱?,則表明已無可用資源。計數(shù)為零時,嘗試減小信號的線程會被阻塞,直到計數(shù)大于零為止。

由于信號無需由同一個線程來獲取和釋放,因此信號可用于異步事件通知,如用于信號處理程序中。同時,由于信號包含狀態(tài),因此可以異步方式使用,而不用象條件變量那樣要求獲取互斥鎖。但是,信號的效率不如互斥鎖高。缺省情況下,如果有多個線程正在等待信號,則解除阻塞的順序是不確定的。信號在使用前必須先初始化,但是信號沒有屬性。

3 初始化信號量

使用sem_init(3RT)可以將sem所指示的未命名信號變量初始化為value。

sem_init語法

int sem_init(sem_t *sem, int pshared, unsigned int value);

#include <semaphore.h>

sem_t sem;

int pshared;

int ret;

int value;

/* initialize a private semaphore */

pshared =0;

value =1;

ret = sem_init(&sem, pshared, value);

如果pshared的值為零,則不能在進程之間共享信號。如果pshared的值不為零,則可以在進程之間共享信號。

注意:

(1)多個線程決不能初始化同一個信號。

(2)不得對其他線程正在使用的信號重新初始化。

#p#

4 初始化進程內(nèi)信號量

pshared為0時,信號只能由該進程內(nèi)的所有線程使用。

#include <semaphore.h>

sem_t sem;

int ret;

int count = 4;

/* to be used within this process only */

ret = sem_init(&sem, 0, count);

5 初始化進程間信號量

pshared不為零時,信號可以由其他進程共享。

#include <semaphore.h>

sem_t sem;

int ret;

int count = 4;

/* to be shared among processes */

ret = sem_init(&sem, 1, count);

6 sem_init返回值

sem_init()在成功完成之后會返回零。其他任何返回值都表示出現(xiàn)了錯誤。如果出現(xiàn)以下任一情況,該函數(shù)將失敗并返回對應的值。

EINVAL

描述:參數(shù)值超過了SEM_VALUE_MAX。

ENOSPC

描述:初始化信號所需的資源已經(jīng)用完。到達信號的SEM_NSEMS_MAX限制。

ENOSYS

描述:系統(tǒng)不支持sem_init()函數(shù)。

EPERM

描述:進程缺少初始化信號所需的適當權(quán)限。

7 增加信號

sem_post語法

int sem_post(sem_t *sem);

#include <semaphore.h>

sem_t sem;

int ret;

ret = sem_post(&sem); /* semaphore is posted */

如果所有線程均基于信號阻塞,則會對其中一個線程解除阻塞。

sem_post返回值

sem_post()在成功完成之后會返回零。其他任何返回值都表示出現(xiàn)了錯誤。如果出現(xiàn)以下情況,該函數(shù)將失敗并返回對應的值。

EINVAL

描述: sem所指示的地址非法。

8 基于信號計數(shù)進行阻塞

使用sem_wait(3RT)可以阻塞調(diào)用線程,直到sem所指示的信號計數(shù)大于零為止,之后以原

子方式減小計數(shù)。

sem_wait語法

int sem_wait(sem_t *sem);

#include <semaphore.h>

sem_t sem;

int ret;

ret = sem_wait(&sem); /* wait for semaphore */

sem_wait返回值

sem_wait()在成功完成之后會返回零。其他任何返回值都表示出現(xiàn)了錯誤。如果出現(xiàn)以下任一情況,該函數(shù)將失敗并返回對應的值。

EINVAL

描述: sem所指示的地址非法。

EINTR

描述:此函數(shù)已被信號中斷。

9 減小信號計數(shù)

使用sem_trywait(3RT)可以在計數(shù)大于零時,嘗試以原子方式減小sem所指示的信號計數(shù)。

sem_trywait語法

int sem_trywait(sem_t *sem);

#include <semaphore.h>

sem_t sem;

int ret;

ret = sem_trywait(&sem); /* try to wait for semaphore*/

此函數(shù)是sem_wait()的非阻塞版本。sem_trywait()在失敗時會立即返回。

sem_trywait返回值

sem_trywait()在成功完成之后會返回零。其他任何返回值都表示出現(xiàn)了錯誤。如果出現(xiàn)以下任一情況,該函數(shù)將失敗并返回對應的值。

EINVAL

描述: sem所指示的地址非法。

EINTR

描述:此函數(shù)已被信號中斷。

EAGAIN

描述:信號已為鎖定狀態(tài),因此該信號不能通過sem_trywait()操作立即鎖定。

10 銷毀信號狀態(tài)

使用sem_destroy(3RT)可以銷毀與sem所指示的未命名信號相關(guān)聯(lián)的任何狀態(tài)。

sem_destroy語法

int sem_destroy(sem_t *sem);

#include <semaphore.h>

sem_t sem;

int ret;

ret = sem_destroy(&sem); /* the semaphore is destroyed */

sem_destroy返回值

sem_destroy()在成功完成之后會返回零。其他任何返回值都表示出現(xiàn)了錯誤。如果出現(xiàn)以

下情況,該函數(shù)將失敗并返回對應的值。

EINVAL

描述: sem所指示的地址非法。

【編輯推薦】

  1. Linux環(huán)境下雙網(wǎng)卡主機路由配置
  2. linux下如何破解windows密碼
  3. Linux下配置JDK和Tomcat
責任編輯:趙寧寧 來源: chinaitlab
相關(guān)推薦

2020-11-10 15:25:26

SemaphoreLinux翻譯

2020-09-25 07:34:40

Linux系統(tǒng)編程信號量

2010-03-16 17:52:27

Java多線程信號量

2020-11-05 09:59:24

Linux內(nèi)核信號量

2024-10-29 15:23:45

Python線程安全

2024-04-10 08:16:20

多線程編程Java并發(fā)編程

2019-11-19 09:00:38

JavaAND信號量

2010-07-15 15:32:10

Perl線程

2021-02-03 20:10:29

Linux信號量shell

2010-04-21 16:25:13

Unix信號量

2010-04-21 16:42:48

Unix信號量

2016-11-23 16:08:24

Python處理器分布式系統(tǒng)

2025-04-16 08:50:00

信號量隔離線程池隔離并發(fā)控制

2021-04-13 09:20:15

鴻蒙HarmonyOS應用開發(fā)

2010-04-21 16:50:31

Unix信號量

2025-04-23 11:00:00

Hystrix隔離模式信號量

2021-09-07 07:53:42

Semaphore 信號量源碼

2010-04-21 15:37:38

Unix信號量

2023-11-23 08:31:51

競爭鎖共享字段

2017-05-11 14:05:25

Consul分布式信號量
點贊
收藏

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