亚洲精品久久久久久久久久久,亚洲国产精品一区二区制服,亚洲精品午夜精品,国产成人精品综合在线观看,最近2019中文字幕一页二页

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

Linux信號量(2):POSIX 信號量

電子設(shè)計 ? 來源:電子設(shè)計 ? 作者:電子設(shè)計 ? 2020-10-29 17:34 ? 次閱讀
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

上一章,講述了 SYSTEM V 信號量,主要運行于進(jìn)程之間,本章主要介紹 POSIX 信號量:有名信號量、無名信號量。

POSIX 信號量

POSIX 信號量進(jìn)程是 3 種 IPC(Inter-Process Communication) 機制之一,3 種 IPC 機制源于 POSIX.1 的實時擴展。Single UNIX Specification 將 3 種機制(消息隊列,信號量和共享存儲)置于可選部分中。在 SUSv4 之前,POSIX 信號量接口已經(jīng)被包含在信號量選項中。在 SUSv4 中,這些接口被移至了基本規(guī)范,而消息隊列和共享存儲接口依然是可選的。

POSIX 信號量接口意在解決 XSI 信號量接口的幾個缺陷。

相比于 XSI 接口,POSIX 信號量接口考慮了更高性能的實現(xiàn)。

POSIX 信號量使用更簡單:沒有信號量集,在熟悉的文件系統(tǒng)操作后一些接口被模式化了。盡管沒有要求一定要在文件系統(tǒng)中實現(xiàn),但是一些系統(tǒng)的確是這么實現(xiàn)的。

POSIX 信號量在刪除時表現(xiàn)更完美?;貞浺幌?,當(dāng)一個 XSI 信號量被刪除時,使用這個信號量標(biāo)識符的操作會失敗,并將 errno 設(shè)置成 EIDRM。使用 POSIX 信號量時,操作能繼續(xù)正常工作直到該信號量的最后一次引用被釋放。

分類

POSIX 信號量是一個 sem_t 類型的變量,但 POSIX 有兩種信號量的實現(xiàn)機制:無名信號量和命名信號量。無名信號量只可以在共享內(nèi)存的情況下,比如實現(xiàn)進(jìn)程中各個線程之間的互斥和同步,因此無名信號量也被稱作基于內(nèi)存的信號量;命名信號量通常用于不共享內(nèi)存的情況下,比如進(jìn)程間通信。

同時,在創(chuàng)建信號量時,根據(jù)信號量取值的不同,POSIX 信號量還可以分為:

二值信號量:信號量的值只有 0 和 1,這和互斥量很類似,若資源被鎖住,信號量的值為 0,若資源可用,則信號量的值為 1;

計數(shù)信號量:信號量的值在 0 到一個大于 1 的限制值之間,該計數(shù)表示可用的資源的個數(shù)。

區(qū)別

有名信號量和無名信號量的差異在于創(chuàng)建和銷毀的形式上,但是其他工作一樣。

無名信號量只能存在于內(nèi)存中,要求使用信號量的進(jìn)程必須能訪問信號量所在的這一塊內(nèi)存,所以無名信號量只能應(yīng)用在同一進(jìn)程內(nèi)的線程之間(共享進(jìn)程的內(nèi)存),或者不同進(jìn)程中已經(jīng)映射相同內(nèi)存內(nèi)容到它們的地址空間中的線程(即信號量所在內(nèi)存被通信的進(jìn)程共享)。意思是說無名信號量只能通過共享內(nèi)存訪問。

相反,有名信號量可以通過名字訪問,因此可以被任何知道它們名字的進(jìn)程中的線程使用。

單個進(jìn)程中使用 POSIX 信號量時,無名信號量更簡單。多個進(jìn)程間使用 POSIX 信號量時,有名信號量更簡單。

聯(lián)系

無論是有名信號量還是無名信號量,都可以通過以下函數(shù)進(jìn)行信號量值操作。

wait(P)

wait 為信號量值減一操作,總共有三個函數(shù),函數(shù)原型如下:


#include

intsem_wait(sem_t*sem);

intsem_trywait(sem_t*sem);

intsem_timedwait(sem_t*sem,conststructtimespec*abs_timeout);

Linkwith-pthread. 這一句表示gcc編譯時,要加-pthread.


返回值:
若成功,返回0;若出錯,返回 -1

sem_wait 的作用是,若 sem 小于 0 ,則線程阻塞于信號量 sem ,直到 sem 大于 0 ;否則信號量值減 1。

sem_trywait 作用與 sem_wait 相同,只是此函數(shù)不阻塞線程,如果 sem 小于 0,直接返回一個錯誤(錯誤設(shè)置為 EAGAIN )。

sem_timedwait 作用也與 sem_wait 相同,第二個參數(shù)表示阻塞時間,如果 sem 小于 0 ,則會阻塞,參數(shù)指定阻塞時間長度。abs_timeout 指向一個結(jié)構(gòu)體,這個結(jié)構(gòu)體由從 1970-01-01 00:00:00 +0000 (UTC) 開始的秒數(shù)和納秒數(shù)構(gòu)成。

結(jié)構(gòu)體定義如下:

structtimespec{
time_ttv_sec;/*Seconds*/
longtv_nsec;/*Nanoseconds[0..999999999]*/
};

如果指定的阻塞時間到了,但是 sem 仍然小于 0 ,則會返回一個錯誤 (錯誤設(shè)置為 ETIMEDOUT )。

post(V)

post 為信號量值加一操作,函數(shù)原型如下:


#include
intsem_post(sem_t*sem);
Linkwith-pthread.
返回值:
若成功,返回0;若出錯,返回 -1

無名信號量

接口函數(shù)

信號量的函數(shù)都以 sem_ 開頭,線程中使用的基本信號函數(shù)有 4 個,他們都聲明在頭文件 semaphore.h 中,該頭文件定義了用于信號量操作的 sem_t 類型:

sem_init

該函數(shù)用于創(chuàng)建信號量,原型如下:


intsem_init(sem_t*sem,intpshared,unsignedintvalue);

功能:該函數(shù)初始化由 sem 指向的信號對象,設(shè)置它的共享選項,并給它一個初始的整數(shù)值。pshared 控制信號量的類型,如果其值為 0,就表示信號量是當(dāng)前進(jìn)程的局部信號量,否則信號量就可以在多個進(jìn)程間共享,value 為 sem 的初始值。返回值:該函數(shù)調(diào)用成功返回 0,失敗返回 -1。

sem_destroy

該函數(shù)用于對用完的信號量進(jìn)行清理,其原型如下:


intsem_destroy(sem_t*sem);

返回值:

成功返回 0,失敗返回 -1。

sem_getvalue 函數(shù)

該函數(shù)返回當(dāng)前信號量的值,通過 restrict 輸出參數(shù)返回。如果當(dāng)前信號量已經(jīng)上鎖(即同步對象不可用),那么返回值為 0,或為負(fù)數(shù),其絕對值就是等待該信號量解鎖的線程數(shù)。


intsem_getvalue(sem_t*restrict,int*restrict);

使用實例

【實例 1】:

#include

#include

#include

#include

#include

#include

#include

#include

sem_tsem;

#definehandle_error(msg)do{/
perror(msg);/
exit(EXIT_FAILURE);/
}while(0)
staticvoidhandler(intsig){
write(STDOUT_FILENO,"sem_post()fromhandler/n",24);
if(sem_post(&sem)==-1)
{
write(STDERR_FILENO,"sem_post()failed/n",18);
_exit(EXIT_FAILURE);
}}
intmain(intargc,char*argv[]){
ints;
structtimespects;
structsigactionsa;

if(argc!=3)
{
fprintf(stderr,"Usage:%s/n",argv[0]);
exit(EXIT_FAILURE);
}

if(sem_init(&sem,0,0)==-1)
handle_error("sem_init");

/*EstablishSIGALRMhandler;setalarmtimerusingargv[1]*/
sa.sa_handler=handler;
sigemptyset(&sa.sa_mask);
sa.sa_flags=0;
if(sigaction(SIGALRM,&sa,NULL)==-1)
handle_error("sigaction");

alarm(atoi(argv[1]));

/*Calculaterelativeintervalascurrenttimeplus
numberofsecondsgivenargv[2]*/

if(clock_gettime(CLOCK_REALTIME,&ts)==-1)
handle_error("clock_gettime");

ts.tv_sec+=atoi(argv[2]);

printf("main()abouttocallsem_timedwait()/n");
while((s=sem_timedwait(&sem,&ts))==-1&&errno==EINTR)
continue;/*Restartifinterruptedbyhandler*/

/*Checkwhathappened*/
if(s==-1)
{
if(errno==ETIMEDOUT)
printf("sem_timedwait()timedout/n");
else
perror("sem_timedwait");
}
else
{
printf("sem_timedwait()succeeded/n");
}

exit((s==0)?EXIT_SUCCESS:EXIT_FAILURE);

}

【實例 2】:

#include

#include

#include

#include

#include

#include

#include

#include

sem_tsem;
void*func1(void*arg){
sem_wait(&sem);
int*running=(int*)arg;
printf("threadfunc1running:%d/n",*running);

pthread_exit(NULL);
}
void*func2(void*arg)
{
printf("threadfunc2running./n");
sem_post(&sem);

pthread_exit(NULL);
}
intmain(void)
{
inta=3;
sem_init(&sem,0,0);
pthread_tthread_id[2];

pthread_create(&thread_id[0],NULL,func1,(void*)&a);
printf("mainthreadrunning./n");
sleep(10);
pthread_create(&thread_id[1],NULL,func2,(void*)&a);
printf("mainthreadstillrunning./n");
pthread_join(thread_id[0],NULL);
pthread_join(thread_id[1],NULL);
sem_destroy(&sem);

return0;
}

有名信號量

有時候也叫命名信號量,之所以稱為命名信號量,是因為它有一個名字、一個用戶 ID、一個組 ID 和權(quán)限。這些是提供給不共享內(nèi)存的那些進(jìn)程使用命名信號量的接口。命名信號量的名字是一個遵守路徑名構(gòu)造規(guī)則的字符串。

接口函數(shù)

sem_open 函數(shù)

該函數(shù)用于創(chuàng)建或打開一個命名信號量,其原型如下:


sem_t*sem_open(constchar*name,intoflag);
sem_t*sem_open(constchar*name,intoflag,mode_tmode,unsignedintvalue);

參數(shù)

name 是一個標(biāo)識信號量的字符串。

oflag 用來確定是創(chuàng)建信號量還是連接已有的信號量。oflag 的參數(shù)可以為 0,O_CREAT 或 O_EXCL:如果為 0,表示打開一個已存在的信號量;如果為 O_CREAT,表示如果信號量不存在就創(chuàng)建一個信號量,如果存在則打開被返回,此時 mode 和 value 都需要指定;如果為 O_CREAT|O_EXCL,表示如果信號量存在則返回錯誤。

mode 用于創(chuàng)建信號量時指定信號量的權(quán)限位,和 open 函數(shù)一樣,包括:S_IRUSR、S_IWUSR、S_IRGRP、S_IWGRP、S_IROTH、S_IWOTH。

value 表示創(chuàng)建信號量時,信號量的初始值。

sem_close 函數(shù)

該函數(shù)用于關(guān)閉命名信號量:


intsem_close(sem_t*);

功能:單個程序可以用 sem_close 函數(shù)關(guān)閉命名信號量,但是這樣做并不能將信號量從系統(tǒng)中刪除,因為命名信號量在單個程序執(zhí)行之外是具有持久性的。當(dāng)進(jìn)程調(diào)用 _exit、exit、exec 或從 main 返回時,進(jìn)程打開的命名信號量同樣會被關(guān)閉。

sem_unlink 函數(shù)功能:sem_unlink 函數(shù)用于在所有進(jìn)程關(guān)閉了命名信號量之后,將信號量從系統(tǒng)中刪除:


intsem_unlink(constchar*name);

信號量操作函數(shù)與無名信號量一樣。

使用實例

#include
#include
#include
#include
#include
#include
#include
#include
#include
#defineSEM_NAME"/sem_name"
sem_t*p_sem;
void*testThread(void*ptr){
sem_wait(p_sem);
sleep(2);
pthread_exit(NULL);}
intmain(void){
inti=0;
pthread_tpid;
intsem_val=0;
p_sem=sem_open(SEM_NAME,O_CREAT,0555,5);

if(p_sem==NULL)
{
printf("sem_open%sfailed!/n",SEM_NAME);
sem_unlink(SEM_NAME);
return-1;
}

for(i=0;i

命名和無名信號量的持續(xù)性

命名信號量是隨內(nèi)核持續(xù)的。當(dāng)命名信號量創(chuàng)建后,即使當(dāng)前沒有進(jìn)程打開某個信號量,它的值依然保持,直到內(nèi)核重新自舉或調(diào)用 sem_unlink()刪除該信號量。

無名信號量的持續(xù)性要根據(jù)信號量在內(nèi)存中的位置確定:

如果無名信號量是在單個進(jìn)程內(nèi)部的數(shù)據(jù)空間中,即信號量只能在進(jìn)程內(nèi)部的各個線程間共享,那么信號量是隨進(jìn)程的持續(xù)性,當(dāng)進(jìn)程終止時他也就消失了;

如果無名信號量位于不同進(jìn)程的共享內(nèi)存區(qū),因此只要該共享內(nèi)存區(qū)仍然存在,該信號量就會一直存在;所以此時無名信號量是隨內(nèi)核的持續(xù)性。

信號量 - 互斥量 - 條件變量

很多時候信號量、互斥量和條件變量都可以在某種應(yīng)用中使用,那這三者的差異有哪些呢?下面列出了這三者之間的差異:

互斥量必須由給它上鎖的線程解鎖;而信號量不需要由等待它的線程進(jìn)行掛出,可以在其他進(jìn)程進(jìn)行掛出操作;

互斥量要么被鎖住,要么被解開,只有這兩種狀態(tài);而信號量的值可以支持多個進(jìn)程 / 線程成功的進(jìn)行 wait 操作;

信號量的掛出操作總是被記住,因為信號量有一個計數(shù)值,掛出操作總會將該計數(shù)值加 1,然而當(dāng)條件變量發(fā)送一個信號時,如果沒有線程等待在條件變量,那么該信號就會丟失。

審核編輯 黃昊宇

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報投訴
  • Linux
    +關(guān)注

    關(guān)注

    88

    文章

    11583

    瀏覽量

    217312
  • Posix
    +關(guān)注

    關(guān)注

    0

    文章

    36

    瀏覽量

    10035
  • 信號量
    +關(guān)注

    關(guān)注

    0

    文章

    53

    瀏覽量

    8728
收藏 人收藏
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

    評論

    相關(guān)推薦
    熱點推薦

    求助,關(guān)于RT-Thread 最新版本timer.c rt_timer_check函數(shù)問題求解

    ;gt;parameter);之前,是否要開啟系統(tǒng)中斷,V4.1.1版本保持關(guān)閉,v5.1.0版本開啟了中斷: v5.1.0 v4.1.1 我在某個串口任務(wù)實現(xiàn)當(dāng)中,使用了信號量的機制,在串口接收
    發(fā)表于 09-25 07:00

    rt_sem_take卡住導(dǎo)致線程無法正常運行怎么解決?

    串口接收數(shù)據(jù)后release信號量,接收線程take sem,高頻大數(shù)據(jù)接受數(shù)據(jù),運行一段時間后接受線程suspend,但是release正常釋放 出現(xiàn)問題問題后查看信息如下: 接受線程為suspend,sem的值一直在增加,考慮了線程棧及線程優(yōu)先級問題,沒有找到根
    發(fā)表于 09-23 08:17

    alloc_socket在不斷創(chuàng)建socket時會不斷新建信號量和互斥鎖,導(dǎo)致內(nèi)存泄漏,怎么解決?

    alloc_socket在不斷創(chuàng)建socket時會不斷新建信號量和互斥鎖,導(dǎo)致內(nèi)存泄漏。 修改前: static struct wiz_socket *alloc_socket(void
    發(fā)表于 09-10 08:22

    中斷發(fā)送信號量不能釋放等待信號量的線程是怎么回事?

    modbus_uart_input(rt_device_t dev, rt_size_t size) { /* 串口接收到數(shù)據(jù)后產(chǎn)生中斷, 調(diào)用此回調(diào)函數(shù), 然后發(fā)送接收信號量
    發(fā)表于 09-10 06:28

    為什么無法接收到信號量?

    只有一個解析線程負(fù)責(zé)接收信號量,永久等待的。有別的幾個線程收到數(shù)據(jù)之后會釋放信號量,設(shè)備剛開始運行是沒問題的,可是運行十幾個小時之后就無法接收到信號量了,有沒有大佬可以幫忙解決一下
    發(fā)表于 09-10 06:21

    【HZ-T536開發(fā)板免費體驗】—— linux 進(jìn)程創(chuàng)建

    Linux進(jìn)程通信方式有這幾種: 1。管道 2信號量 3。消息隊列 4。共享內(nèi)存 在本帖子中,我會講解fork(),exit()系統(tǒng)調(diào)用的實踐。通過應(yīng)用編程來實現(xiàn)系統(tǒng)調(diào)用。 1,進(jìn)程創(chuàng)建 打開
    發(fā)表于 09-01 20:49

    安科瑞繼電器或晶體管輸出開關(guān)輸入信號隔離器

    1. 概述 安科瑞開關(guān)輸入信號隔離器 ,輸入干接點或NAMUR型接近開關(guān)信號,繼電器或晶體管隔離輸出??赏ㄟ^撥碼開關(guān)設(shè)置輸出和輸入同相或反相邏輯控制,設(shè)置開啟或關(guān)閉線路故障檢測功能。該產(chǎn)品需要獨立供電,輸入、輸出和電源三端隔離
    的頭像 發(fā)表于 05-20 15:07 ?345次閱讀
    安科瑞繼電器或晶體管輸出開關(guān)<b class='flag-5'>量</b>輸入<b class='flag-5'>信號</b>隔離器

    模擬對傳模塊能做什么

    模擬對傳模塊是一種用于連續(xù)信號傳輸?shù)脑O(shè)備,能夠?qū)⒛M輸入(如電壓、電流、溫度、壓力等)通過有線或無線方式從一個位置傳輸?shù)搅硪粋€位置,并進(jìn)行高精度還原。與開關(guān)(離散
    的頭像 發(fā)表于 04-17 15:16 ?486次閱讀

    4G模擬對傳模塊,無線通訊,實時同步模擬信號

    。 一、基本概念 4G模擬對傳模塊,一種支持第四代移動通信網(wǎng)絡(luò)技術(shù)(4GLTE)的無線通信模塊,同時具備模擬信號的傳輸能力。通過將模擬信號
    的頭像 發(fā)表于 04-10 16:54 ?537次閱讀

    FreeRTOS(V9.0)中創(chuàng)建信號量的函數(shù)都沒有被定義,因此用不了,怎么解決

    問題背景:我想要使用信號量,結(jié)果查找了整個工程都沒有創(chuàng)建信號量的函數(shù)。我還以為是我自己移植有問題,因此還特地下載了其他人移植好的工程進(jìn)行編程。結(jié)果也沒有創(chuàng)建信號量的函數(shù)。不論是二值信號量
    發(fā)表于 03-13 09:30

    工業(yè)級模擬信號實時傳輸解決方案分享,你肯定用得到

    一、簡介 DTD509F系列模擬信號無線傳輸器通常是由一個無線信號發(fā)射終端和一個無線信號接收終端組成,也可以根據(jù)現(xiàn)場實現(xiàn)一點對多點或者多點對一點的
    的頭像 發(fā)表于 03-08 15:14 ?717次閱讀
    工業(yè)級模擬<b class='flag-5'>量</b><b class='flag-5'>信號</b>實時傳輸解決方案分享,你肯定用得到

    工控自動化領(lǐng)域:數(shù)字量信號與模擬信號的差異解析

    在工控自動化的神秘世界里,信號如同傳遞指令和信息的使者,而數(shù)字量信號和模擬信號則是其中的兩大主角。它們各自有著獨特的 “性格” 和 “使命”,在不同的場景中發(fā)揮著關(guān)鍵作用。下面,就讓
    的頭像 發(fā)表于 02-20 09:14 ?878次閱讀

    基于OpenHarmony標(biāo)準(zhǔn)系統(tǒng)的C++公共基礎(chǔ)類庫案例:Semaphore

    的公共資源變量;創(chuàng)建5個線程,每個線程做5次for循環(huán),for循環(huán)的內(nèi)容是獲取無名信號量,并修改公共資源變量;(2)有名信號量使用方法定義1個有名信號量,1個供有名
    的頭像 發(fā)表于 02-10 18:08 ?549次閱讀
    基于OpenHarmony標(biāo)準(zhǔn)系統(tǒng)的C++公共基礎(chǔ)類庫案例:Semaphore

    模擬信號的應(yīng)用和優(yōu)缺點

    在現(xiàn)代工業(yè)自動化、環(huán)境監(jiān)測、科學(xué)研究等領(lǐng)域,模擬信號作為一種基本且重要的信號形式,扮演著不可或缺的角色。本文將對模擬信號進(jìn)行深度解析,探
    的頭像 發(fā)表于 02-03 11:26 ?1810次閱讀

    安科瑞ARTU/K8 8開關(guān)信號采集裝置單元

    電源:AC/DC 220V 2 技術(shù)參數(shù) 16路狀態(tài)采集 開關(guān)信號采集裝置 遙信單元? 3 外形尺寸 “三遙"定義: 遙信
    的頭像 發(fā)表于 12-18 14:46 ?762次閱讀
    安科瑞ARTU/K8 8開關(guān)<b class='flag-5'>量</b><b class='flag-5'>信號</b>采集裝置單元