国产毛片a精品毛-国产毛片黄片-国产毛片久久国产-国产毛片久久精品-青娱乐极品在线-青娱乐精品

查看: 2912|回復(fù): 1
打印 上一主題 下一主題

【武漢華嵌】Linux進(jìn)程間通信之信號(hào)量

[復(fù)制鏈接]
跳轉(zhuǎn)到指定樓層
樓主
發(fā)表于 2011-11-1 15:02:11 | 只看該作者 回帖獎(jiǎng)勵(lì) |倒序?yàn)g覽 |閱讀模式
作者:武漢華嵌 嵌入式培訓(xùn)中心技術(shù)部

信號(hào)量是一種用于提供不同進(jìn)程間或一個(gè)給定進(jìn)程的不同線程間同步手段的原語(yǔ)。在UNIX下有三種分別如下:
  • Posix有名信號(hào)量;
  • Posix基于內(nèi)存的信號(hào)量;
  • System V信號(hào)量。
在這里只和大家分享下有關(guān)System V信號(hào)量。
System V通過(guò)定義計(jì)數(shù)信號(hào)量集來(lái)對(duì)信號(hào)量的操作,計(jì)數(shù)信號(hào)量集是一個(gè)或多個(gè)信號(hào)量構(gòu)成一個(gè)集合,其中每個(gè)都是計(jì)數(shù)信號(hào)量。對(duì)于系統(tǒng)中的每個(gè)信號(hào)量集,內(nèi)核維護(hù)一個(gè)如下的信息結(jié)構(gòu),它定義在頭文件中。
struct semid_ds{
struct ipc_perm  sem_perm;     /* operation permission struct */
struct sem      *sem_base;     /* ptr to array of semaphores in set */
uishort          sem_nsems;    /* #of semaphores in set */
time_t          sem_otime;    /* time of last semop() */
time_t          sem_ctime;    /* time of creation or last IPC_SET */
};

成員struct sem結(jié)構(gòu)如下:
         struct sem{
         ushort_t   semval;    /* semaphore value , nonnegative */
         short      sempid;    /* PID of last successful semop(), SETVAL, SETALL */
         ushort_t   semncnt;   /* awaiting semval > current value */
         ushort_t   semzcnt;    /* awaiting semval = 0 */
         };

注意在struct semid_ds結(jié)構(gòu)中的sem_base含有指向某個(gè)sem結(jié)構(gòu)數(shù)組的指針:當(dāng)前信號(hào)量集中的每個(gè)信號(hào)對(duì)應(yīng)其中一個(gè)數(shù)組元素。我們可以把內(nèi)核中的某個(gè)選定信號(hào)量圖解成指向一個(gè)sem結(jié)構(gòu)數(shù)組的一個(gè)semid_ds結(jié)構(gòu)。圖解如下:
file:///C:/DOCUME~1/jack/LOCALS~1/Temp/msohtml1/01/clip_image001.png
有了以上的理論,那么接下來(lái)我們來(lái)探討下如何對(duì)這樣的信號(hào)量進(jìn)行操作,linux操作系統(tǒng)為我們提供了操作system v信號(hào)量的API函數(shù),以下就開始講解這些API函數(shù)。
  • semget函數(shù)創(chuàng)建一個(gè)信號(hào)量集或訪問一個(gè)已存在的信號(hào)量集。
#include
int semget(key_t key, int nsems, int oflag);
該函數(shù)成功返回時(shí),其返回值是一個(gè)稱為信號(hào)量標(biāo)識(shí)符的整數(shù),semop和semctl使用它。出錯(cuò)則返回-1。
nsems參數(shù)指定集合中的信號(hào)量數(shù)。如果我們創(chuàng)建一個(gè)新的信號(hào)量集,而只是訪問一個(gè)已存在的集合,那就可以把該參數(shù)指定為0。一旦創(chuàng)建完一個(gè)信號(hào)量集,我們就不能改變其中的信號(hào)量數(shù)。
oflag值是一些權(quán)限值的組合,如果是創(chuàng)建一個(gè)信號(hào)量集,那么得在此oflag的基礎(chǔ)上或上O_CREAT或者是O_CREAT|O_EXCL。
此函數(shù)不可以對(duì)創(chuàng)建的信號(hào)量集中的信號(hào)量進(jìn)行初始化,對(duì)信號(hào)量的初始化是通過(guò)另外的一個(gè)函數(shù)semctl進(jìn)行的。
  • 通過(guò)semctl函數(shù)對(duì)信號(hào)量集中的信號(hào)量進(jìn)行初始化。
#include
int semctl(int semid, int semnum, int cmd, …./* union semun arg*/ )
         semid標(biāo)識(shí)其操作待控制的信號(hào)量集。
         semnum標(biāo)識(shí)該信號(hào)量集內(nèi)的某個(gè)成員(0, 1等待,直到nsems -1)。semnum值僅僅用于GETVAL、SETVAL、GETNCNT、GETZCNT和GETPID命令。
         第四個(gè)參數(shù)是可選的,取決于第三個(gè)參數(shù)cmd。union semnu結(jié)構(gòu)如下:
union semnu{
         int              val;     /* used for SETVAL only */
         struct semid_ds   *buf;    /* used for IPC_SET and IPC_STAT */
         ushort          *array;   /* used for GETALL and SETALL */
         };
         這個(gè)聯(lián)合體并沒有出現(xiàn)在任何頭文件中,因而必須由應(yīng)用程序聲明。
第三個(gè)參數(shù)cmd可以取以下值:
GETVAL  把semval的當(dāng)前值作為函數(shù)返回值返回。
SETVAL  把semval值設(shè)置為arg.val。如果操作成功,那么相應(yīng)信號(hào)量在所有進(jìn)程是的信號(hào)
                   量調(diào)整值(semadj)將被置為0。
IPC_RMID 把由semid指定的信號(hào)量集從系統(tǒng)中刪除掉。
IPC_SET 設(shè)置所指定信號(hào)量集的semid_ds結(jié)構(gòu)中的某些成員。
IPC_SET R 返回所指定信號(hào)量集當(dāng)前的semid_ds結(jié)構(gòu)。
  • 使用semget得到一個(gè)信號(hào)量集,使用semctl設(shè)置信號(hào)量集中的信號(hào)量,那么對(duì)信號(hào)量集中的信號(hào)通過(guò)semop來(lái)進(jìn)行操作。
#include
int semop(int semid, struct sembuf *opsptr, size_t nops);
semid標(biāo)識(shí)其操作的信號(hào)量集。
其中opsptr指向一個(gè)如下結(jié)構(gòu)的數(shù)組:
Struct sembuf{
Short    sem_num;     /* semaphore number: 0, 1, …., nsems-1 */
Short    sem_op;      /* semaphore operation: <0, 0, >0 */
Short    sem_flag;     /* semaphore flags : 0, IPC_NOWAITE, SEM_UNDO */
};
nops參數(shù)指出由opsptr指向的sembuf結(jié)構(gòu)數(shù)組中元素的數(shù)目。該數(shù)組中的生個(gè)元素給目標(biāo)信號(hào)量集內(nèi)某個(gè)特定的信號(hào)量指定一個(gè)操作。這個(gè)特定的信號(hào)量由sem)num指定,0代表第一個(gè)元素,1代表第二個(gè)元素,依次類推,直到nsems-1,其中nsems是目標(biāo)信號(hào)量集內(nèi)成員信號(hào)量的數(shù)目。
semop對(duì)信號(hào)的操作是由sem_op的值確定的,以下是對(duì)sem_op取值的分析:
  • 、sem_op 為正數(shù)時(shí),會(huì)把sem_op的值加到操作的信號(hào)量的信號(hào)值上。如果sem_flg被設(shè)置為IPC_UNDO,無(wú)論程序正常結(jié)束與否,都會(huì)把信號(hào)值重新設(shè)置為調(diào)用semop函數(shù)前得值。這對(duì)應(yīng)于進(jìn)程釋放占用的資源數(shù)。
  • 、sem_op為負(fù)數(shù)時(shí),如果要操作的信號(hào)量的值大于或者等于sem_op的絕對(duì)值,則從信號(hào)量值中加上sen_op的值。如果信號(hào)量值小于sem_op的絕對(duì)值,則有如下:
    • 如果sem_flg的值為IPC_NOWAIT,那么semop出錯(cuò),返回EAGAIN。
    • 如果sem_flg沒有設(shè)置為IPC_NOWAIT,則該信號(hào)量的semncnt的值加1,然后此進(jìn)程掛起,直到此信號(hào)量的值大于sem_op的絕對(duì)值,才執(zhí)行semop操作;或者此信號(hào)量從系統(tǒng)中刪除,此時(shí)semop返回EIDRM;或者該掛起進(jìn)程捕捉到信號(hào),從信號(hào)處理程序返回,此時(shí),semop出錯(cuò)返回EINTR。
    • 如果sen_op的值為0,則調(diào)用進(jìn)程希望等到該信號(hào)量值變成0。
  • 、sem_op為0時(shí),那么調(diào)用者希望等待到semval變?yōu)?。如果sem_op已經(jīng)是0,那就立即返回。

以下是利用信號(hào)量來(lái)進(jìn)行一個(gè)PV操作,實(shí)現(xiàn)代碼如下:

//初始化信號(hào)量
int init_sem(int semid, int semval)
{
         SYS_NUM semnu;
         semnu.sem_val = semval;
         if((semctl(semid, 0, SETVAL, semnu)) < 0)
         {
                   perror("init_sem semctl");
                   return -1;
         }
         return 0;
}

//對(duì)信號(hào)量進(jìn)行p操作
int sem_p(int semid)
{
         SYS_SEM sembu;

         sembu.sem_num = 0;
         sembu.sem_op = -1;
         sembu.sem_flg = SEM_UNDO;

         if((semop(semid, &sembu, 1)) < 0)
         {
                   perror("sem_p semop");
                   return -1;
         }
         return 0;
}

//對(duì)信號(hào)量進(jìn)行v操作
int sem_v(int semid)
{
         SYS_SEM sembu;

         sembu.sem_num = 0;
         sembu.sem_op = 1;
         sembu.sem_flg = SEM_UNDO;

         if((semop(semid, &sembu, 1)) < 0)
         {
                   perror("sem_v semop");
                   return -1;
         }
         return 0;
}

//刪除信號(hào)量集
int del_sem(int semid)
{
         if((semctl(semid, 0, IPC_RMID)) < 0)
         {
                   perror("del_sem semctl");
                   return -1;
         }
         return 0;
}


總結(jié):
         信號(hào)量往往是用來(lái)同步的,保護(hù)共享內(nèi)存。

更多技術(shù)文章敬請(qǐng)關(guān)注:武漢華嵌-嵌入式培訓(xùn)專家,國(guó)內(nèi)領(lǐng)先的嵌入式服務(wù)機(jī)構(gòu),
http://www.embedhq.org
沙發(fā)
 樓主| 發(fā)表于 2013-4-8 14:34:44 | 只看該作者
武漢華嵌嵌入式培訓(xùn)
咨詢QQ:1216677636   
        QQ:572658958
咨詢電話:027-87780211

本版積分規(guī)則

關(guān)于我們  -  服務(wù)條款  -  使用指南  -  站點(diǎn)地圖  -  友情鏈接  -  聯(lián)系我們
電子工程網(wǎng) © 版權(quán)所有   京ICP備16069177號(hào) | 京公網(wǎng)安備11010502021702
快速回復(fù) 返回頂部 返回列表
主站蜘蛛池模板: 天堂综合网 | 丝袜美腿视频一区二区三区 | 91尤物在线 | 亚洲欧美日本人成在线观看 | 2019天天操天天干天天透 | 国产未成女年一区二区 | 国产在线视频国产永久视频 | 国产真实伦对白在线播放 | 极品五月天 | 久久美女福利视频 | 久久91久久91精品免费观看 | 久久精品女人毛片国产 | 一级毛片aaa片免费观看 | 久久精品亚洲牛牛影视 | 字幕网在线观看 | 四虎精品国产一区二区三区 | 最近最新2019年中文字幕 | 羞羞网站免费 | 99热国产这里只有精品99 | 欧美操操网 | 精品视频一区二区三区四区五区 | 91网站入口最新 | 97精品在线 | 国产香蕉久久 | 一个人www免费观看 一个人hd免费完整高清视频 | 日本免费在线看 | 韩国伦理妈妈的朋友在线观看 | 亚洲欧美v国产一区二区 | 4hu影院永久在线播放 | 亚洲综合激情六月婷婷在线观看 | 落跑甜心电视剧高清全集免费观看 | 国产一区二区三区手机在线观看 | 四虎国产精品永久一区 | 日韩精品在线看 | 国产h视频在线观看高清 | 国产日韩精品视频 | 国产精品大全国产精品 | 婷婷视频网 | 国产一区精品在线观看 | 97av麻豆蜜桃一区二区 | 国产羞羞的视频在线观看免费 |