中文亚洲精品无码_熟女乱子伦免费_人人超碰人人爱国产_亚洲熟妇女综合网

當(dāng)前位置: 首頁 > news >正文

1688網(wǎng)站上自己做模版專業(yè)營銷團(tuán)隊(duì)公司

1688網(wǎng)站上自己做模版,專業(yè)營銷團(tuán)隊(duì)公司,網(wǎng)站開發(fā)范圍,長春做網(wǎng)站公司哪家好15.信號燈(信號量) Linux中的信號燈即信號量是一種用于進(jìn)程間同步或互斥的機(jī)制,它主要用于控制對共享資源的訪問。 在Linux系統(tǒng)中,信號燈作為一種進(jìn)程間通信(IPC)的方式,與其他如管道、FIFO或共享內(nèi)存等IPC方式不同&…

15.信號燈(信號量)

Linux中的信號燈即信號量是一種用于進(jìn)程間同步或互斥的機(jī)制,它主要用于控制對共享資源的訪問。

在Linux系統(tǒng)中,信號燈作為一種進(jìn)程間通信(IPC)的方式,與其他如管道、FIFO或共享內(nèi)存等IPC方式不同,信號燈主要用于同步或互斥控制,以確保多個進(jìn)程之間能夠協(xié)調(diào)地訪問共享資源。信號燈可以看作是內(nèi)存中的一個標(biāo)志,進(jìn)程可以通過檢查信號燈的狀態(tài)來決定是否可以安全地訪問某些共享資源

要點(diǎn)

  1. 創(chuàng)建和操作:要在Linux中使用信號燈,首先需要創(chuàng)建一個信號燈,并指定其初始值。對于二值信號燈,這個初始值通常是1,表示資源一開始是可用的。
  2. 等待和釋放:進(jìn)程可以執(zhí)行等待操作來測試信號燈的值,如果信號燈的值大于0,則進(jìn)程可以繼續(xù)執(zhí)行并將信號燈的值減1;如果值為0,則進(jìn)程必須等待直到信號燈的值變?yōu)檎龜?shù)。
  3. 共享資源控制:信號燈提供了一種機(jī)制,使得進(jìn)程能夠根據(jù)信號燈的狀態(tài)來判斷是否可以訪問某些共享資源。這類似于互斥鎖,確保了在任何時候只有一個進(jìn)程可以訪問臨界區(qū)。
  4. 進(jìn)程間通信:除了同步和互斥,信號燈還可以作為進(jìn)程間通信的一種方式。它們存在于內(nèi)核空間,與共享內(nèi)存和消息隊(duì)列一起構(gòu)成了Linux中主要的IPC通信方式。
  5. 有名信號燈: 可以通過路徑名在進(jìn)程間共享,因此不同進(jìn)程可以通過已知的路徑名來訪問同一個有名信號燈。 適用于需要在不同進(jìn)程間進(jìn)行同步的場景。
  6. 無名信號燈: 只能存在于內(nèi)存中,因此使用無名信號燈的進(jìn)程必須能夠訪問相同的內(nèi)存區(qū)域。通過共享內(nèi)存的方式創(chuàng)建,不依賴于文件系統(tǒng)中的路徑名。適用于單進(jìn)程內(nèi)多線程間的同步或在已經(jīng)映射相同內(nèi)存內(nèi)容的多個進(jìn)程之間的同步。
  7. System V信號燈:Linux支持System V的信號燈,這是一種傳統(tǒng)的信號燈實(shí)現(xiàn),用于在同一系統(tǒng)內(nèi)的進(jìn)程間進(jìn)行同步和互斥。

互斥和同步 是信號燈通常用于解決并發(fā)中的兩個主要問題:

  1. 互斥:確保當(dāng)一個進(jìn)程使用共享資源時,其他進(jìn)程不能同時訪問該資源。例如,打印設(shè)備只能由一個進(jìn)程使用,其他嘗試訪問打印設(shè)備的進(jìn)程必須等待,直到當(dāng)前進(jìn)程完成打印任務(wù)。

  2. 同步:確保進(jìn)程間的執(zhí)行順序符合特定的依賴關(guān)系。例如,一個進(jìn)程生成數(shù)據(jù),另一個進(jìn)程消費(fèi)這些數(shù)據(jù),消費(fèi)者進(jìn)程需要等待生產(chǎn)者進(jìn)程生成數(shù)據(jù)后才能繼續(xù)執(zhí)行。

PV操作

信號燈的工作原理基于PV操作,其中P操作用于請求資源(減少信號量的值),而V操作用于釋放資源(增加信號量的值)。

  • P操作“proberen”(嘗試):如果信號量的值為正,則將其減一,允許進(jìn)程繼續(xù)執(zhí)行。如果信號量的值為0或負(fù),則進(jìn)程被阻塞,直到信號量的值變?yōu)檎龜?shù)。

  • V操作“verhogen”(釋放):將信號量的值加一,如果有其他進(jìn)程因等待該信號量而被阻塞,則其中一個進(jìn)程會被喚醒。

POSIX是一組用于確保操作系統(tǒng)間可移植性的IEEE標(biāo)準(zhǔn),主要針對Unix系統(tǒng)。POSIX標(biāo)準(zhǔn)為操作系統(tǒng)提供了一套共通的規(guī)則,使得軟件開發(fā)更加高效,同時也讓用戶能夠在不同的系統(tǒng)之間無縫地遷移和運(yùn)行應(yīng)用程序。

有名信號燈

用到的函數(shù)主要有:

  1. sem_open 有名信號燈打開
  2. sem_close 有名信號燈關(guān)閉
  3. sem_unlink 有名信號燈的刪除
  4. sem_wait 信號燈P操作,申請資源
  5. sem_post 信號燈V操作,釋放資源

sem_open 函數(shù)

  1. 原型

    #include <fcntl.h>
    #include <sys/stat.h>
    #include <semaphore.h>
    sem_t *sem_open(const char *name, int oflag, mode_t mode, unsigned int value);
    
  2. 功能:創(chuàng)建或打開一個有名信號量(named semaphore)的函數(shù)

  3. 參數(shù)

    • name:信號量的名稱,用于標(biāo)識信號量。
    • oflag:打開選項(xiàng),可以是以下值的組合:
      • O_CREAT:如果信號量不存在,則創(chuàng)建一個新的信號量。
      • O_EXCL:與O_CREAT一起使用,表示如果信號量已存在,則返回錯誤。
      • O_RDWR:允許對信號量進(jìn)行讀寫操作。
    • mode:設(shè)置信號量的權(quán)限,通常設(shè)置為0644。
    • value:信號量的初始值。
  4. 返回值

    • 成功時,返回一個指向信號量的指針。
    • 失敗時,返回SEM_FAILURE(通常是NULL)。

sem_close 函數(shù)

  1. 原型

    #include <semaphore.h>
    int sem_close(sem_t *sem);
    
  2. 功能:用于關(guān)閉一個信號量的函數(shù)

  3. 參數(shù)

    • sem:指向要關(guān)閉的信號量的指針
  4. 返回值

    • 成功時,返回0。
    • 失敗時,返回-1,并設(shè)置errno。

sem_unlink 函數(shù)

  1. 原型

    #include <semaphore.h>
    int sem_unlink(const char *name);
    
  2. 功能:刪除一個命名信號量

  3. 參數(shù)

    • name:要刪除的信號量的名稱
  4. 返回值

    • 成功時,返回0
    • 失敗時,返回-1,并設(shè)置errno

sem_wait 函數(shù)

  1. 原型

    #include <semaphore.h>
    int sem_wait(sem_t *sem);
    
  2. 功能:”P操作“等待一個信號量。當(dāng)信號量的值大于0時,該函數(shù)會將信號量的值減1,并立即返回。如果信號量的值為0,則該函數(shù)會阻塞當(dāng)前線程,直到信號量的值大于0為止。

  3. 參數(shù)

    • sem:指向要等待的信號量的指針。
  4. 返回值

    • 成功時,返回0。
    • 失敗時,返回-1,并設(shè)置errno。

sem_post 函數(shù)

  1. 原型

    #include <semaphore.h>
    int sem_post(sem_t *sem);
    
  2. 功能:”V操作“增加一個信號量的值。當(dāng)信號量的值大于0時,如果有其他線程正在等待該信號量,則sem_post函數(shù)會喚醒其中一個等待的線程。如果沒有線程在等待,那么信號量的值簡單地增加,它與sem_wait函數(shù)相對應(yīng).

  3. 參數(shù)

    • sem:指向要操作的信號量的指針。
  4. 返回值

    • 成功時,返回0。
    • 失敗時,返回-1,并設(shè)置errno。

示例-有名信號燈使用

使用信號量和共享內(nèi)存實(shí)現(xiàn)的簡單進(jìn)程間通信(IPC)示例

一個簡單的命令行界面,用戶可以在命令行中輸入字符串,并將其存儲到共享內(nèi)存中。通過信號量來實(shí)現(xiàn)進(jìn)程間的同步,確保數(shù)據(jù)的讀寫操作不會發(fā)生沖突

tes_semw.c 寫程序

#include <fcntl.h>
#include <sys/stat.h>
#include <semaphore.h>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <signal.h>void delsemfile(int sig)
{
sem_unlink("mysem_w");  // 刪除名為"mysem_w"的信號量
exit(0);                // 退出程序
}int main()
{
sem_t *sem_r,*sem_w;     // 定義兩個信號量指針,分別用于讀和寫操作
key_t key;               // 定義鍵值,用于生成共享內(nèi)存標(biāo)識符
int shmid;               // 定義共享內(nèi)存標(biāo)識符
char *shmaddr;           // 定義共享內(nèi)存地址指針struct sigaction act;    // 定義信號處理結(jié)構(gòu)體
act.sa_handler = delsemfile;  // 設(shè)置信號處理函數(shù)為delsemfile
act.sa_flags = 0;        // 設(shè)置信號處理標(biāo)志為0
sigemptyset(&act.sa_mask);   // 清空信號集sigaction(SIGINT,&act,NULL); // 注冊信號處理函數(shù),當(dāng)接收到SIGINT信號時調(diào)用delsemfile函數(shù)key = ftok(".",100);      // 生成鍵值,用于創(chuàng)建共享內(nèi)存標(biāo)識符
if(key<0)
{perror("ftok");      // 如果生成失敗,打印錯誤信息return 0;            
}shmid = shmget(key,500,0666|IPC_CREAT);  // 創(chuàng)建共享內(nèi)存段,大小為500字節(jié),權(quán)限為0666,如果不存在則創(chuàng)建
if(shmid<0)
{perror("shmget");    // 如果創(chuàng)建失敗,打印錯誤信息return 0;           
}shmaddr = shmat(shmid,NULL,0);  // 將共享內(nèi)存段附加到進(jìn)程的地址空間,并獲取共享內(nèi)存地址指針sem_r = sem_open("mysem_r",O_CREAT|O_RDWR,0666,0);  // 創(chuàng)建名為"mysem_r"的信號量,初始值為0
sem_w = sem_open("mysem_w",O_CREAT|O_RDWR,0666,1);  // 創(chuàng)建名為"mysem_w"的信號量,初始值為1while(1)
{sem_wait(sem_w);    // 等待名為"mysem_w"的信號量變?yōu)榉橇阒?/span>printf(">");        // 輸出提示符">"fgets(shmaddr,500,stdin);  // 從標(biāo)準(zhǔn)輸入讀取一行字符串,存儲到共享內(nèi)存中sem_post(sem_r);    // 增加名為"mysem_r"的信號量的值,表示數(shù)據(jù)已寫入共享內(nèi)存
}
}

tes_semr.c 讀程序

#include <fcntl.h>
#include <sys/stat.h>
#include <semaphore.h>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <signal.h>void delsemfile(int sig)
{
sem_unlink("mysem_r");  // 刪除名為"mysem_r"的信號量
exit(0);                // 退出程序
}int main(){sem_t *sem_r,*sem_w;     // 定義兩個信號量指針,分別用于讀和寫操作
key_t key;               // 定義鍵值,用于生成共享內(nèi)存標(biāo)識符
int shmid;               // 定義共享內(nèi)存標(biāo)識符
char *shmaddr;           // 定義共享內(nèi)存地址指針
struct sigaction act;    // 定義信號處理結(jié)構(gòu)體
act.sa_handler = delsemfile;  // 設(shè)置信號處理函數(shù)為delsemfile
act.sa_flags = 0;        // 設(shè)置信號處理標(biāo)志為0
sigemptyset(&act.sa_mask);   // 清空信號集sigaction(SIGINT,&act,NULL); // 注冊信號處理函數(shù),當(dāng)接收到SIGINT信號時調(diào)用delsemfile函數(shù)key = ftok(".",100);      // 生成鍵值,用于創(chuàng)建共享內(nèi)存標(biāo)識符
if(key<0)
{perror("ftok");      // 如果生成失敗,打印錯誤信息return 0;            
}shmid = shmget(key,500,0666|IPC_CREAT);  // 創(chuàng)建共享內(nèi)存段,大小為500字節(jié),權(quán)限為0666,如果不存在則創(chuàng)建
if(shmid<0)
{perror("shmget");    // 如果創(chuàng)建失敗,打印錯誤信息return 0;            
}shmaddr = shmat(shmid,NULL,0);  // 將共享內(nèi)存段附加到進(jìn)程的地址空間,并獲取共享內(nèi)存地址指針sem_r = sem_open("mysem_r",O_CREAT|O_RDWR,0666,0);  // 創(chuàng)建名為"mysem_r"的信號量,初始值為0
sem_w = sem_open("mysem_w",O_CREAT|O_RDWR,0666,1);  // 創(chuàng)建名為"mysem_w"的信號量,初始值為1while(1)
{sem_wait(sem_r);    // 等待名為"mysem_r"的信號量變?yōu)榉橇阒?/span>printf("%s\n",shmaddr);  // 輸出共享內(nèi)存中的字符串sem_post(sem_w);    // 增加名為"mysem_w"的信號量的值,表示數(shù)據(jù)已讀取完成
}
}

在這里插入圖片描述

運(yùn)行效果如圖,實(shí)現(xiàn)了兩個進(jìn)程通訊

可以通過命令ls /dev/shm查看信號量文件;在Linux系統(tǒng)中,/dev/shm目錄是用于存放共享內(nèi)存和信號量文件的特殊目錄

ctrl + c退出程序后,捕獲到SIGINT信號后執(zhí)行delsemfile()刪除信號量文件

無名信號燈

用到的函數(shù)有:

  1. sem_init 初始化無名信號量
  2. sem_destory 銷毀無名信號量
  3. sem_wait 信號燈P操作,申請資源
  4. sem_post 信號燈V操作,釋放資源

sem_init 函數(shù)

  1. 原型

    #include <semaphore.h>
    int sem_init(sem_t *sem, int pshared, unsigned int value);
    
  2. 功能:初始化一個無名信號量

  3. 參數(shù)

    • sem:指向要初始化的信號量的指針。
    • pshared:指定信號量的類型,如果為0,則表示該信號量是進(jìn)程私有的;如果為非0值,則表示該信號量是進(jìn)程間共享的。
    • value:指定信號量的初始值。
  4. 返回值

    • 成功時,返回0;
    • 失敗時,返回-1,并設(shè)置errno。

sem_destory 函數(shù)

  1. 原型

    #include <semaphore.h>
    int sem_destroy(sem_t *sem);
    
  2. 功能:銷毀一個無名信號量

  3. 參數(shù)

    • sem:指向要銷毀的信號量的指針。
  4. 返回值

    • 成功時,返回0;
    • 失敗時,返回-1,并設(shè)置errno。
  5. 注意:只有當(dāng)信號量的引用計(jì)數(shù)變?yōu)?時,才能安全地銷毀它。如果還有其他線程或進(jìn)程正在等待該信號量,那么銷毀操作將失敗,并且errno將被設(shè)置為EBUSY。在這種情況下,需要確保所有使用該信號量的線程或進(jìn)程都已經(jīng)結(jié)束,然后再嘗試銷毀它。

示例-無名信號燈使用

使用信號量和共享內(nèi)存實(shí)現(xiàn)的簡單進(jìn)程間通信(IPC)示例。主要功能是在一個進(jìn)程中輸入字符串,另一個進(jìn)程中讀取并打印這些字符串。

#include <fcntl.h>
#include <sys/stat.h> 
#include <semaphore.h>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <signal.h>
#include <pthread.h>sem_t sem_r,sem_w; // 定義兩個信號量,用于讀寫同步
char *shmaddr; // 共享內(nèi)存地址指針void destroysem(int sig) // 信號處理函數(shù),用于銷毀信號量并退出程序
{
sem_destroy(&sem_r); // 銷毀讀信號量
sem_destroy(&sem_w); // 銷毀寫信號量
exit(0); // 退出程序
}void *readmem(void *arg) // 讀取共享內(nèi)存中的字符串并打印的線程函數(shù)
{
while(1)
{sem_wait(&sem_r); // 等待讀信號量printf("%s\n",shmaddr); // 打印共享內(nèi)存中的字符串sem_post(&sem_w); // 釋放寫信號量
}
}int main()
{
key_t key; // 鍵值
int shmid; // 共享內(nèi)存標(biāo)識符struct sigaction act; // 信號處理結(jié)構(gòu)體
act.sa_handler = destroysem; // 設(shè)置信號處理函數(shù)
act.sa_flags = 0; // 設(shè)置信號處理標(biāo)志
sigemptyset(&act.sa_mask); // 清空信號集sigaction(SIGINT,&act,NULL); // 注冊信號處理函數(shù)key = ftok(".",100); // 生成鍵值
if(key<0)
{perror("ftok"); // 輸出錯誤信息return 0;
}shmid = shmget(key,500,0666|IPC_CREAT); // 創(chuàng)建共享內(nèi)存
if(shmid<0)
{perror("shmget"); // 輸出錯誤信息return 0;
}shmaddr = shmat(shmid,NULL,0); // 將共享內(nèi)存映射到進(jìn)程地址空間sem_init(&sem_r,0,0); // 初始化讀信號量,初始值為0
sem_init(&sem_w,0,1); // 初始化寫信號量,初始值為1pthread_t tid; // 線程標(biāo)識符
pthread_create(&tid,NULL,readmem,NULL); // 創(chuàng)建線程,執(zhí)行readmem函數(shù)while(1)
{sem_wait(&sem_w); // 等待寫信號量printf(">"); // 提示用戶輸入fgets(shmaddr,500,stdin); // 從標(biāo)準(zhǔn)輸入讀取字符串并存儲到共享內(nèi)存中sem_post(&sem_r); // 釋放讀信號量
}
}

在這里插入圖片描述

運(yùn)行效果如圖

在父進(jìn)程中,它循環(huán)接收用戶輸入的數(shù)據(jù)并將其寫入共享內(nèi)存中。在子進(jìn)程中,它循環(huán)讀取共享內(nèi)存中的數(shù)據(jù)并打印出來。

System V 信號燈

System V 信號燈是一種用于進(jìn)程間同步和互斥的機(jī)制,它允許多個進(jìn)程共享資源而不會產(chǎn)生沖突。

  1. 信號燈集合:System V 信號燈可以是一個或多個計(jì)數(shù)信號燈的集合。這意味著可以同時操作集合中的任意多個信號燈,以協(xié)調(diào)進(jìn)程間的訪問順序。
  2. 信號燈操作:System V 信號燈的操作通常涉及三個步驟:初始化(創(chuàng)建)、P 操作(等待資源)和 V 操作(釋放資源)。P 操作用于請求資源,如果資源不可用則進(jìn)程將等待;V 操作用于釋放資源,使得其他等待該資源的進(jìn)程可以繼續(xù)執(zhí)行
  3. 避免死鎖:通過申請多個資源時使用 System V 信號燈,可以減少死鎖的風(fēng)險。死鎖是指兩個或多個進(jìn)程在互相等待對方釋放資源時無法繼續(xù)執(zhí)行的狀態(tài)。

System V 信號燈是一種重要的同步機(jī)制,它在多進(jìn)程編程中扮演著關(guān)鍵角色,確保了資源的有序訪問和數(shù)據(jù)的一致性。

用到的函數(shù)有:

  1. semget 創(chuàng)建/打開信號燈
  2. semop 對信號燈集合中的信號量進(jìn)行P - V操作
  3. semctl 信號燈集合的控制(初始化/刪除)

semget 函數(shù)

  1. 原型

    #include <sys/sem.h>
    int semget(key_t key, int nsems, int semflg);
    
  2. 功能:獲取一個信號量集的標(biāo)識符

  3. 參數(shù)

    • key:是一個鍵值,用于唯一標(biāo)識一個信號量集。通常使用ftok()函數(shù)生成。
    • nsems:指定需要創(chuàng)建或獲取的信號量數(shù)量。
    • semflg:設(shè)置信號量集的訪問權(quán)限和創(chuàng)建標(biāo)志??梢允且韵轮档慕M合:
      • IPC_CREAT:如果信號量集不存在,則創(chuàng)建一個新的信號量集。
      • IPC_EXCL:與IPC_CREAT一起使用,表示如果信號量集已經(jīng)存在,則返回錯誤。
      • 0:表示不設(shè)置任何特殊標(biāo)志。
  4. 返回值

    • 如果成功,返回信號量集的標(biāo)識符(非負(fù)整數(shù))。
    • 如果失敗,返回-1,并設(shè)置errno為相應(yīng)的錯誤碼。

semop 函數(shù)

  1. 原型

    #include <sys/sem.h>
    int semop(int semid, struct sembuf *sops, unsigned nsops);
    
  2. 功能:改變信號量的值,對信號燈集合中的信號量進(jìn)行P - V操作

  3. 參數(shù)

    • semid:是一個信號量集的標(biāo)識符,由semget()函數(shù)返回。
    • sops:是一個指向struct sembuf結(jié)構(gòu)體數(shù)組的指針,該數(shù)組定義了要執(zhí)行的操作。
    • nsops:指定sops數(shù)組中操作的數(shù)量。

    struct sembuf結(jié)構(gòu)體:

    struct sembuf {unsigned short sem_num;  // 信號量編號short sem_op;            // 操作類型short sem_flg;           // 操作標(biāo)志
    };
    

    各個字段的含義如下:

    • sem_num:指定要操作的信號量的編號。如果設(shè)置為0,則表示對整個信號量集進(jìn)行操作。
    • sem_op:指定要對信號量執(zhí)行的操作類型。
      • 當(dāng)sem_op> 0,它表示進(jìn)程釋放控制的資源,即信號量的值將增加sem_op的數(shù)量。
      • 當(dāng)sem_op= 0,如果沒有設(shè)置IPC_NOWAIT標(biāo)志,調(diào)用進(jìn)程將進(jìn)入睡眠狀態(tài)直到信號量的值為0;如果設(shè)置了該標(biāo)志且信號量值不為0,則進(jìn)程不會進(jìn)入睡眠,而是直接返回EAGAIN。
      • 當(dāng)sem_op< 0,它表示嘗試獲取資源使用權(quán),信號量的值將增加sem_op的絕對值。如果此時信號量的值小于或等于sem_op的絕對值,操作將會阻塞,直到信號量的值大于或等于sem_op的絕對值。
    • sem_flg:指定操作的標(biāo)志。可以是以下值的組合:
      • IPC_NOWAIT:非阻塞模式,如果無法立即執(zhí)行操作,則立即返回。
      • SEM_UNDO:撤銷之前的操作。
      • 0:不設(shè)置任何特殊標(biāo)志。
  4. 返回值

    • 如果成功,返回0。
    • 如果失敗,返回-1,并設(shè)置errno為相應(yīng)的錯誤碼。

semctl 函數(shù)

  1. 原型

    #include <sys/sem.h>
    int semctl(int semid, int semnum, int cmd, ...);
    
  2. 功能:控制信號量集

  3. 參數(shù)

    • semid:是一個信號量集的標(biāo)識符,由semget()函數(shù)返回。
    • semnum:指定要操作的信號量的編號。如果設(shè)置為0,則表示對整個信號量集進(jìn)行操作。
    • cmd:指定要執(zhí)行的命令??梢允且韵轮抵?#xff1a;
      • IPC_RMID:刪除信號量集。(常用)
      • IPC_SET:設(shè)置信號量集的屬性。(常用)
      • IPC_STAT:獲取信號量集的狀態(tài)信息。(常用)
      • SETVAL:設(shè)置信號燈的值,需要用到第四個參數(shù):共用體。(常用)
      • IPC_INFO:獲取系統(tǒng)支持的信號量集的最大數(shù)量和當(dāng)前使用的數(shù)量。
      • SEM_STAT:獲取指定信號量的狀態(tài)信息。
      • GETALL:獲取所有信號量的值。
      • GETNCNT:獲取等待某個信號量變?yōu)榉橇阒档倪M(jìn)程數(shù)。
      • GETPID:獲取最后一個操作指定信號量的進(jìn)程ID。
      • GETVAL:獲取指定信號量的值。
      • GETZCNT:獲取等待某個信號量變?yōu)榱阒档倪M(jìn)程數(shù)。
      • SETALL:設(shè)置所有信號量的值。
    • ...:根據(jù)cmd的不同,可能需要傳遞額外的參數(shù)。
  4. 返回值

    • 如果成功,返回相應(yīng)的結(jié)果或狀態(tài)信息。
    • 如果失敗,返回-1,并設(shè)置errno為相應(yīng)的錯誤碼

示例-System V信號燈使用

基于信號量和共享內(nèi)存的進(jìn)程間通信(IPC)示例。它創(chuàng)建了一個父子進(jìn)程,并使用信號量和共享內(nèi)存進(jìn)行數(shù)據(jù)傳遞。

#include <semaphore.h>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <sys/types.h>
#include <sys/sem.h>#define SEM_READ   0
#define SEM_WRITE  1//semctl函數(shù)用到的參數(shù)
union semun {
int val;
};               // P操作函數(shù),用于對信號量進(jìn)行減一操作
void Poperation(int semid,int semindex)
{
struct sembuf sbuf;
sbuf.sem_num =  semindex;
sbuf.sem_op = -1;
sbuf.sem_flg = 0;semop(semid,&sbuf,1);
}// V操作函數(shù),用于對信號量進(jìn)行加一操作
void Voperation(int semid,int semindex)
{
struct sembuf sbuf;
sbuf.sem_num =  semindex;
sbuf.sem_op = 1;
sbuf.sem_flg = 0;semop(semid,&sbuf,1);
}int main()
{
key_t key; // 定義鍵值key
char *shmaddr; // 共享內(nèi)存地址指針
int semid,shmid; // 信號量和共享內(nèi)存的ID
key = ftok(".",100); // 生成鍵值
if(key<0)
{perror("ftok"); // 如果生成失敗,輸出錯誤信息return 0;
}semid = semget(key,2,IPC_CREAT |0666); // 創(chuàng)建信號量集合
if(semid<0)
{perror("semget"); // 如果創(chuàng)建失敗,輸出錯誤信息return 0;
}
shmid = shmget(key,500,IPC_CREAT |0666); // 創(chuàng)建共享內(nèi)存
shmaddr = shmat(shmid,NULL,0); // 將共享內(nèi)存映射到進(jìn)程地址空間
union semun mysem; // 定義信號量聯(lián)合體
mysem.val = 0; // 初始化讀信號量的值為0
semctl(semid,SEM_READ,SETVAL,mysem); // 設(shè)置讀信號量的值
mysem.val = 1; // 初始化寫信號量的值為1
semctl(semid,SEM_WRITE,SETVAL,mysem); // 設(shè)置寫信號量的值pid_t pid; // 定義進(jìn)程ID
pid = fork(); // 創(chuàng)建子進(jìn)程
if(pid<0)
{perror("fork"); // 如果創(chuàng)建失敗,輸出錯誤信息shmctl(shmid,IPC_RMID,NULL); // 刪除共享內(nèi)存semctl(semid,0,IPC_RMID); // 刪除信號量集合exit(-1);
}else if(pid == 0)
{// 子進(jìn)程循環(huán)讀取共享內(nèi)存中的數(shù)據(jù)并打印while(1){Poperation(semid,SEM_READ); // 對讀信號量進(jìn)行P操作printf("%s\n",shmaddr); // 打印共享內(nèi)存中的數(shù)據(jù)Voperation(semid,SEM_WRITE); // 對寫信號量進(jìn)行V操作}
}
else
{// 父進(jìn)程循環(huán)接收用戶輸入的數(shù)據(jù)并寫入共享內(nèi)存while(1){Poperation(semid,SEM_WRITE); // 對寫信號量進(jìn)行P操作printf(">"); // 提示用戶輸入數(shù)據(jù)fgets(shmaddr,32,stdin); // 從標(biāo)準(zhǔn)輸入讀取數(shù)據(jù)并寫入共享內(nèi)存Voperation(semid,SEM_READ); // 對讀信號量進(jìn)行V操作}
}
}

在這里插入圖片描述

運(yùn)行結(jié)果如圖

在父進(jìn)程中,它循環(huán)接收用戶輸入的數(shù)據(jù)并將其寫入共享內(nèi)存中。在子進(jìn)程中,它循環(huán)讀取共享內(nèi)存中的數(shù)據(jù)并打印出來。

http://www.risenshineclean.com/news/5506.html

相關(guān)文章:

  • 阿里云網(wǎng)站如何建設(shè)視頻新浪微博指數(shù)查詢
  • 快速 模板 做網(wǎng)站百度網(wǎng)址安全檢測
  • 焦作市住房和城鄉(xiāng)建設(shè)局網(wǎng)站百度競價推廣登陸
  • 潛江做網(wǎng)站太原做網(wǎng)站推廣的公司
  • 韶關(guān)網(wǎng)站建設(shè)網(wǎng)站排名seo
  • 用ps做網(wǎng)站網(wǎng)頁百度排名服務(wù)
  • 網(wǎng)站建設(shè)崗位工作范圍怎樣注冊網(wǎng)站建立網(wǎng)頁
  • 成都網(wǎng)站外包優(yōu)化公司可以免費(fèi)發(fā)外鏈的論壇
  • 推進(jìn)網(wǎng)站集約化建設(shè)的作用推廣普通話手抄報一等獎
  • 網(wǎng)絡(luò)優(yōu)化報告seo外包網(wǎng)絡(luò)公司
  • 做網(wǎng)站下載別人的圖算不算侵權(quán)北京網(wǎng)站sem、seo
  • 整站關(guān)鍵詞排名優(yōu)化員工培訓(xùn)
  • 網(wǎng)站的空間的提供商南京網(wǎng)站制作設(shè)計(jì)
  • 畢業(yè)答辯ppt網(wǎng)站開發(fā)百度大數(shù)據(jù)分析平臺
  • 網(wǎng)頁設(shè)計(jì)師證書查詢官網(wǎng)google seo怎么優(yōu)化
  • 精美網(wǎng)頁設(shè)計(jì)源碼網(wǎng)站seo優(yōu)化外包顧問
  • 龍山建設(shè)集團(tuán)有限公司網(wǎng)站云南優(yōu)化公司
  • 怎么知道網(wǎng)站是誰做的b站推廣入口2023
  • 織夢網(wǎng)站怎樣做seo長尾關(guān)鍵詞查詢工具
  • 哪里有html5網(wǎng)站建設(shè)檢測網(wǎng)站是否安全
  • 網(wǎng)絡(luò)服務(wù)提供者有哪些新泰網(wǎng)站seo
  • 中山疫情防控最新通知關(guān)于進(jìn)一步優(yōu)化
  • 微網(wǎng)站建設(shè)哪家好好看的seo網(wǎng)站
  • 餐飲服務(wù)案例100例谷歌seo運(yùn)營
  • 企業(yè)郵箱在哪里登陸seo技巧分享
  • 畢業(yè)設(shè)計(jì)做網(wǎng)站想法百度搜索排名機(jī)制
  • 怎么用ps做網(wǎng)站超鏈接百度網(wǎng)址大全網(wǎng)站大全
  • 建電子商城網(wǎng)站百度賬號找回
  • 青島的設(shè)計(jì)公司黑帽seo排名技術(shù)
  • 網(wǎng)站建設(shè)的基本規(guī)范有什么小時seo