国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

【Linux】多線程 之 POSIX信號(hào)量

這篇具有很好參考價(jià)值的文章主要介紹了【Linux】多線程 之 POSIX信號(hào)量。希望對(duì)大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請(qǐng)大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問。

1. 概念

信號(hào)量又稱為 信號(hào)燈
本質(zhì)就是一個(gè)計(jì)數(shù)器,用于描述臨界資源數(shù)目的

sem: 0 -> 1 -> 0
若臨界資源只有1個(gè),則sem設(shè)為1,當(dāng)要使用臨界資源時(shí),sem由1變?yōu)?,其他人在想申請(qǐng),則申請(qǐng)不到掛起排隊(duì),等待釋放臨界資源時(shí) sem由0變?yōu)? ,才可以再申請(qǐng)臨界資源
這種信號(hào)量稱為 二元信號(hào)量 ,等同于互斥鎖

每一個(gè)線程,在訪問對(duì)應(yīng)的資源時(shí),先申請(qǐng)信號(hào)量,
申請(qǐng)成功,表示該線程允許使用該資源
申請(qǐng)不成功,表示目前無法使用該資源

2. 信號(hào)量的工作機(jī)制

信號(hào)量機(jī)制類似于看電影買票,一種資源的預(yù)訂機(jī)制
申請(qǐng)信號(hào)量成功,相當(dāng)于預(yù)定了一部分資源

【Linux】多線程 之 POSIX信號(hào)量,linux,linux

判斷條件是否滿足,決定了后續(xù)行為
信號(hào)量已經(jīng)是資源的計(jì)數(shù)器,申請(qǐng)信號(hào)量成功,本身就表明資源可用
申請(qǐng)信號(hào)量失敗,本身表明資源不可用
本質(zhì)就是把判斷轉(zhuǎn)換成信號(hào)量的申請(qǐng)行為

3. 認(rèn)識(shí)接口

POSIX信號(hào)量 和system V 信號(hào)量 作用相同,都是用于同步操作,達(dá)到無沖突的訪問共享資源目的,但POSIX可以用于線程間同步


sem_init ——初始化信號(hào)量

輸入 man sem_init

【Linux】多線程 之 POSIX信號(hào)量,linux,linux

sem :表示信號(hào)量
pshared : 0表示線程間共享 非零表示進(jìn)程間共享
value : 信號(hào)量初始值 (計(jì)數(shù)器值初始化為多少)

sem_destroy——銷毀信號(hào)量

輸入 man sem_destroy

【Linux】多線程 之 POSIX信號(hào)量,linux,linux

對(duì)已經(jīng)初始化的信號(hào)量進(jìn)行銷毀

sem_wait ——申請(qǐng)信號(hào)量

輸入 man sem_wait

【Linux】多線程 之 POSIX信號(hào)量,linux,linux

進(jìn)行申請(qǐng)信號(hào)量的操作,使信號(hào)量的值減1

sem_post ——釋放信號(hào)量

輸入 man sem_post

【Linux】多線程 之 POSIX信號(hào)量,linux,linux

進(jìn)行釋放信號(hào)量的操作,使信號(hào)量的值加1

4. 基于環(huán)形隊(duì)列的生產(chǎn)消費(fèi)模型

原理解析

環(huán)形隊(duì)列實(shí)際上使用數(shù)組模擬的

【Linux】多線程 之 POSIX信號(hào)量,linux,linux

數(shù)組多開一個(gè)空間是為了解決判滿的問題


【Linux】多線程 之 POSIX信號(hào)量,linux,linux

若為空,則 thread和tail 在同一個(gè)位置


【Linux】多線程 之 POSIX信號(hào)量,linux,linux

若為滿,則tail的下一個(gè)位置為head


【Linux】多線程 之 POSIX信號(hào)量,linux,linux

生產(chǎn)者向tail中push數(shù)據(jù) 即生產(chǎn)
消費(fèi)者向head中pop數(shù)據(jù) 即消費(fèi)


生產(chǎn)者 和消費(fèi)者 關(guān)心的資源 是一樣的嗎?
不一樣, 生產(chǎn)者關(guān)心整個(gè)環(huán)形隊(duì)列的空間(商店是否裝滿貨物)
消費(fèi)者關(guān)心的是 數(shù)據(jù),(商店是否還有貨物,有貨物就買)


【Linux】多線程 之 POSIX信號(hào)量,linux,linux

head 和tail什么時(shí)候訪問 同一個(gè)區(qū)域?
有一個(gè)很大的桌子,存在像鐘表的0-12點(diǎn)刻度的區(qū)域,在每個(gè)刻度中放入一個(gè)盤子
有兩個(gè)人A和B同時(shí)進(jìn)入房間看到桌子,A往盤子中放蘋果,B在后面拿蘋果
A和B約定:B不能超過A,一個(gè)盤子只能放一個(gè)蘋果

當(dāng)A和B開始,桌子上沒有蘋果時(shí) ,或者 桌子上全都是蘋果時(shí),都會(huì)訪問同一個(gè)盤子
環(huán)形隊(duì)列 為空 ,或者環(huán)形隊(duì)列為滿 會(huì)訪問 同一個(gè)區(qū)域

當(dāng)隊(duì)列為空,指向同一個(gè)位置,存在競(jìng)爭(zhēng)關(guān)系,
讓生產(chǎn)者先運(yùn)行 (只有當(dāng)生產(chǎn)者產(chǎn)生數(shù)據(jù)后,消費(fèi)者才能拿到數(shù)據(jù))

當(dāng)隊(duì)列為滿時(shí),指向同一個(gè)位置,存在競(jìng)爭(zhēng)關(guān)系,
讓消費(fèi)者先運(yùn)行 (只有當(dāng)消費(fèi)者拿數(shù)據(jù)后,生產(chǎn)者才能生產(chǎn))


【Linux】多線程 之 POSIX信號(hào)量,linux,linux

生產(chǎn)者關(guān)心空間,空間本身也是資源,所以要給生產(chǎn)者定義一個(gè)信號(hào)量sem_room ,其初始值為N
P(sem_room) —— 申請(qǐng)空間信號(hào)量

生產(chǎn)者生產(chǎn)數(shù)據(jù)在當(dāng)前空間,則對(duì)應(yīng)的數(shù)據(jù)+1,所以消費(fèi)者可以拿數(shù)據(jù)
V(sem_data) ——數(shù)據(jù)信號(hào)量的值+1

消費(fèi)者關(guān)心數(shù)據(jù),信號(hào)量為sem_data,其初始值為0
P(sem_data) —— 申請(qǐng)數(shù)據(jù)信號(hào)量

消費(fèi)者把數(shù)據(jù)拿走,當(dāng)前空間就被閑置出來了,所以生產(chǎn)者可以放數(shù)據(jù)
V(sem_room) ——空間信號(hào)量的值+1

代碼

代碼解析

首先在ringqueue.hpp中創(chuàng)建一個(gè)ringqueue類


【Linux】多線程 之 POSIX信號(hào)量,linux,linux

在main函數(shù)中使用new創(chuàng)建出rq隊(duì)列
為了保證生產(chǎn)者和消費(fèi)者看到同一份資源,所以兩者回調(diào)函數(shù)的參數(shù)args都為rq


【Linux】多線程 之 POSIX信號(hào)量,linux,linux

productorRoutine的回調(diào)函數(shù)中 使用 隊(duì)列rq的push,將數(shù)據(jù)插入到隊(duì)列中 即生產(chǎn)
consumerRoutine的回調(diào)函數(shù)中 使用 隊(duì)列rq的pop,把隊(duì)列中的數(shù)據(jù)取出 即消費(fèi)


ringqueue類

ringqueue類中

【Linux】多線程 之 POSIX信號(hào)量,linux,linux

在上述講解原理時(shí),數(shù)據(jù)信號(hào)量只有消費(fèi)者關(guān)心,空間信號(hào)量只有生產(chǎn)者關(guān)心

構(gòu)造
【Linux】多線程 之 POSIX信號(hào)量,linux,linux

將環(huán)形隊(duì)列ring大小和_cap(容量)初始化為N

0表示線程間共享,將數(shù)據(jù)信號(hào)量 初始化為0,將空間信號(hào)量初始化為整個(gè)環(huán)形隊(duì)列的容量
(對(duì)于兩者的初始化值大小,在原理處都有詳細(xì)解釋)

析構(gòu)
【Linux】多線程 之 POSIX信號(hào)量,linux,linux

由于在構(gòu)造時(shí),對(duì)信號(hào)量進(jìn)行初始化,所以需要銷毀信號(hào)量

push ——生產(chǎn)

要生產(chǎn)之前要保證符合條件,才能夠進(jìn)行生產(chǎn),所以要進(jìn)行P操作——申請(qǐng)信號(hào)量

【Linux】多線程 之 POSIX信號(hào)量,linux,linux

在使用信號(hào)量時(shí),是不需要判斷的
因?yàn)樾盘?hào)量是一把計(jì)數(shù)器,本質(zhì)為把對(duì)資源就緒的情況,由在臨界區(qū)內(nèi)轉(zhuǎn)到臨界區(qū)外
它本身就是描述臨界資源數(shù)量的,所以就不用進(jìn)入臨界區(qū)后判斷臨界資源是否滿足條件


【Linux】多線程 之 POSIX信號(hào)量,linux,linux

生產(chǎn)者和消費(fèi)者可能訪問同一個(gè)位置,大概率訪問不同的位置
所以生產(chǎn)者和消費(fèi)者要有自己的下標(biāo) 用于 表示兩者的位置


【Linux】多線程 之 POSIX信號(hào)量,linux,linux

不斷進(jìn)行P操作,在空間上插入數(shù)據(jù)
沒有空間就需要消費(fèi)者進(jìn)行消費(fèi)(V操作),將數(shù)據(jù)拿走下·

【Linux】多線程 之 POSIX信號(hào)量,linux,linux

當(dāng)tail達(dá)到多開一個(gè)空間位置,實(shí)際上相當(dāng)于再次回到head開頭的位置
所以使用%=,模擬環(huán)形隊(duì)列


【Linux】多線程 之 POSIX信號(hào)量,linux,linux

將 sem_wait 和sem_post借助 函數(shù) P和V完成封裝
再次使用時(shí),只需調(diào)用P V即可實(shí)現(xiàn)

【Linux】多線程 之 POSIX信號(hào)量,linux,linux

pop ——消費(fèi)
【Linux】多線程 之 POSIX信號(hào)量,linux,linux

不斷進(jìn)行P操作,將數(shù)據(jù)從空間上拿走,空間都閑置出來了
就需要生產(chǎn)者進(jìn)行生產(chǎn)(V操作),在空間上放置數(shù)據(jù)
文章來源地址http://www.zghlxwxcb.cn/news/detail-572275.html

代碼實(shí)現(xiàn)

Ringqueue.hpp

#include<iostream>
#include<vector>
#include<semaphore.h>//信號(hào)量頭文件
static const int N=5;//設(shè)置環(huán)形隊(duì)列的大小

template<class T>
class ringqueue
{
private:
  void P(sem_t &s)
  {
     sem_wait(&s); 
  }
  void V(sem_t&s)
  {
     sem_post(&s);
  }
public:
    ringqueue(int num=N)
    : _ring(num),_cap(num)
    {
        //信號(hào)量初始化
        sem_init(&_data_sem,0,0);
        sem_init(&_space_sem,0,num);
        _c_step=_p_step=0;//生產(chǎn)和消費(fèi)下標(biāo)都為0
    }
    ~ringqueue()
    {
        //銷毀信號(hào)量
     sem_destroy(&_data_sem);
     sem_destroy(&_space_sem);
    }

    void push(const T&in)//生產(chǎn)
    {
      P(_space_sem);//P操作 申請(qǐng)信號(hào)量
      _ring[_p_step++]=in;//將數(shù)據(jù)放入生產(chǎn)位置
      _p_step%=_cap;
      V(_data_sem);//V操作 釋放信號(hào)量
    }
    void pop(T*out)//消費(fèi) 
    {
       P(_data_sem);//P操作
       *out=_ring[_c_step++];//將該位置的數(shù)據(jù)給與out
       _c_step%=_cap;
       V(_space_sem);//V操作
    }
private:
   int _c_step;//消費(fèi)者位置下標(biāo)
   int _p_step;//生產(chǎn)者位置下標(biāo)
   std::vector<int> _ring;//充當(dāng)環(huán)形隊(duì)列
   int  _cap;//環(huán)形隊(duì)列的容器大小
   sem_t _data_sem;//數(shù)據(jù)信號(hào)量
   sem_t _space_sem;//空間信號(hào)量 
};

makefile
ringqueue:main.cc
	g++ -o $@ $^ -std=c++11 -lpthread
.PHONY:clean
clean:
	rm -f ringqueue 
main.cc

#include"Ringqueue.hpp"
#include<pthread.h>
#include<unistd.h>
using namespace std;
void*consumerRoutine(void*args)
{
  ringqueue<int>*rq=(ringqueue<int>*)args;
  while(true)
  {
  int data=0;
  rq->pop(&data);//從隊(duì)列取出數(shù)據(jù) 消費(fèi)
  cout<<"consumer done:"<<data<<endl;
  sleep(1);
  }
}
void*productorRoutine(void*args) 
{
 ringqueue<int>*rq=(ringqueue<int>*)args;
 while(true)
 {
   int data=1;
   rq->push(data);//將數(shù)據(jù)插入隊(duì)列中 生產(chǎn)
   cout<<"productor done:"<<data<<endl;
 }
}

int main()
{
   ringqueue<int>*rq=new ringqueue<int>();
   pthread_t c;//消費(fèi)者
   pthread_t p;//生產(chǎn)者
   //創(chuàng)建線程
   pthread_create(&c,nullptr,consumerRoutine,rq);
     pthread_create(&p,nullptr,productorRoutine,rq);

     pthread_join(c,nullptr);
     pthread_join(p,nullptr);
    return 0;
}

到了這里,關(guān)于【Linux】多線程 之 POSIX信號(hào)量的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場(chǎng)。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請(qǐng)注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請(qǐng)點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • 線程同步、生產(chǎn)者消費(fèi)模型和POSIX信號(hào)量

    線程同步、生產(chǎn)者消費(fèi)模型和POSIX信號(hào)量

    gitee倉(cāng)庫(kù): 1.阻塞隊(duì)列代碼:https://gitee.com/WangZihao64/linux/tree/master/BlockQueue 2.環(huán)形隊(duì)列代碼:https://gitee.com/WangZihao64/linux/tree/master/ringqueue 概念 : 利用線程間共享的全局變量進(jìn)行同步的一種機(jī)制,主要包括兩個(gè)動(dòng)作:一個(gè)線程等待\\\"條件變量的條件成立\\\"而掛起;另一個(gè)線程使“

    2024年02月03日
    瀏覽(23)
  • 【系統(tǒng)編程】線程安全(POSIX信號(hào)量、互斥鎖、讀寫鎖等)

    【系統(tǒng)編程】線程安全(POSIX信號(hào)量、互斥鎖、讀寫鎖等)

    (??? ),Hello我是 祐言QAQ 我的博客主頁(yè):C/C++語(yǔ)言,數(shù)據(jù)結(jié)構(gòu),Linux基礎(chǔ),ARM開發(fā)板,網(wǎng)絡(luò)編程等領(lǐng)域UP?? 快上??,一起學(xué)習(xí),讓我們成為一個(gè)強(qiáng)大的攻城獅! 送給自己和讀者的一句雞湯??: 集中起來的意志可以擊穿頑石! 作者水平很有限,如果發(fā)現(xiàn)錯(cuò)誤,請(qǐng)?jiān)谠u(píng)論區(qū)指

    2024年02月10日
    瀏覽(106)
  • 【Linux C | 多線程編程】線程同步 | 信號(hào)量(無名信號(hào)量) 及其使用例子

    【Linux C | 多線程編程】線程同步 | 信號(hào)量(無名信號(hào)量) 及其使用例子

    ??博客主頁(yè)??:??https://blog.csdn.net/wkd_007?? ??博客內(nèi)容??:??嵌入式開發(fā)、Linux、C語(yǔ)言、C++、數(shù)據(jù)結(jié)構(gòu)、音視頻?? ??本文內(nèi)容??:??介紹 ?? ??金句分享??:??你不能選擇最好的,但最好的會(huì)來選擇你——泰戈?duì)?? ?發(fā)布時(shí)間?: 本文未經(jīng)允許,不得轉(zhuǎn)發(fā)?。?!

    2024年04月26日
    瀏覽(27)
  • 『Linux』第九講:Linux多線程詳解(五)_ 信號(hào)量

    『Linux』第九講:Linux多線程詳解(五)_ 信號(hào)量

    「前言」文章是關(guān)于Linux多線程方面的知識(shí),上一篇是?Linux多線程詳解(四),今天這篇是 Linux多線程詳解(五),內(nèi)容大致是信號(hào)量,講解下面開始! 「歸屬專欄」Linux系統(tǒng)編程 「主頁(yè)鏈接」個(gè)人主頁(yè) 「筆者」楓葉先生(fy) 「楓葉先生有點(diǎn)文青病」「每篇一句」 求其上,

    2024年02月07日
    瀏覽(18)
  • 一文搞定Linux線程間通訊 / 線程同步方式-互斥鎖、讀寫鎖、自旋鎖、信號(hào)量、條件變量、信號(hào)等等

    目錄 線程間通訊 / 線程同步方式 鎖機(jī)制 互斥鎖(Mutex) 讀寫鎖(rwlock) 自旋鎖(spin) 信號(hào)量機(jī)制(Semaphore) 條件變量機(jī)制 信號(hào)(Signal) 線程間通訊 / 線程同步方式 p.s 以下有很多段落是直接引用,沒有使用 markdown 的 “引用” 格式,出處均已放出。 參考 / 引用: 100as

    2024年02月10日
    瀏覽(24)
  • 第三章 Linux多線程開發(fā) 線程取消 屬性 同步 互斥鎖 死鎖 讀寫鎖 生產(chǎn)者消費(fèi)者 信號(hào)量
  • 【Linux學(xué)習(xí)】多線程——信號(hào)量 | 基于環(huán)形隊(duì)列的生產(chǎn)者消費(fèi)者模型 | 自旋鎖 | 讀寫鎖

    【Linux學(xué)習(xí)】多線程——信號(hào)量 | 基于環(huán)形隊(duì)列的生產(chǎn)者消費(fèi)者模型 | 自旋鎖 | 讀寫鎖

    ??作者:一只大喵咪1201 ??專欄:《Linux學(xué)習(xí)》 ??格言: 你只管努力,剩下的交給時(shí)間! 之前在學(xué)習(xí)進(jìn)程間通信的時(shí)候,本喵簡(jiǎn)單的介紹過一下信號(hào)量,今天在這里進(jìn)行詳細(xì)的介紹。 這是之前寫的基于阻塞隊(duì)列的生產(chǎn)者消費(fèi)者模型中向阻塞隊(duì)列中push任務(wù)的代碼。 上面代碼

    2024年02月07日
    瀏覽(21)
  • linux(信號(hào)量)

    linux(信號(hào)量)

    1.回顧信號(hào)量的概念 2.認(rèn)識(shí)信號(hào)量對(duì)應(yīng)的操作函數(shù) 3.認(rèn)識(shí)一個(gè)環(huán)形隊(duì)列 4.結(jié)合sem+環(huán)形隊(duì)列寫生產(chǎn)者消費(fèi)者模型 --------------------------------------------------------------------------------------------------------------------------------- 1.回顧信號(hào)量的概念 ?每個(gè)人想進(jìn)放映廳看電影,第一件事就是買票

    2024年02月11日
    瀏覽(42)
  • linux信號(hào)量

    linux信號(hào)量

    通過學(xué)習(xí)linux的信號(hào)量,對(duì)linux的信號(hào)量進(jìn)行了編程。

    2024年02月10日
    瀏覽(20)
  • 【Linux】淺談信號(hào)量

    【Linux】淺談信號(hào)量

    tips:system V 是一套標(biāo)準(zhǔn),共享內(nèi)存,信號(hào)量,消息隊(duì)列屬于system V。 進(jìn)程A和進(jìn)程B進(jìn)行通信時(shí),假如進(jìn)程A向物理內(nèi)存的共享區(qū)寫入\\\"Hello World\\\",但是當(dāng)進(jìn)程A寫入了\\\"Hello\\\"時(shí),進(jìn)程B就向內(nèi)存讀取了,所以只讀取到了\\\"Hello\\\",這就導(dǎo)致進(jìn)程A想向進(jìn)程B發(fā)送的信息,進(jìn)程B讀取不完整,

    2024年02月05日
    瀏覽(18)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請(qǐng)作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包