[Linux管道和IPC]使用信號量和共享內(nèi)存進行父子進程通信

#include <stdio.h>
#include <stdlib.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <sys/types.h>
#include <unistd.h>
#include <string.h>
#include <sys/sem.h>
#define SHM_SIZE 1024    //共享內(nèi)存的大小
int main(int argc,char *argv[])
{
  int ret,        //臨時變量
  pid,        //進程id
  sme_id,        //保存信號量描述符
  shm_id;        //保存共享內(nèi)存描述符
  key_t     sme_key,    //保存信號量鍵值
  shm_key;    //保存共享內(nèi)存鍵值
  char *shmp;        //指向共享內(nèi)存的首地址
  struct shmid_ds dsbuf;    //定義共享內(nèi)存信息結(jié)構(gòu)變量
  struct sembuf lock = {0, -1, SEM_UNDO};        //信號量上鎖操作的數(shù)組指針
  struct sembuf unlock = {0, 1, SEM_UNDO | IPC_NOWAIT};//信號量解鎖操作的數(shù)組指針
  shm_key = ftok(*(argv+1), 2);    //獲取信號量鍵值
  if(shm_key < 0)
  {
    perror("ftok");    //調(diào)用ftok函數(shù)出錯
    exit(0);
  }
  sme_id = semget(shm_key, 1, IPC_CREAT | 0666);    //獲取信號量ID
  if(sme_id < 0)
  {
    perror("semget");  //調(diào)用semget函數(shù)出錯
    exit(0);
  }
  shm_key = ftok(*(argv+2), 1);    //獲取共享內(nèi)存鍵值
  if(shm_key < 0)
  {
    perror("ftok");
    exit(0);
  }
  shm_id = shmget(shm_key, SHM_SIZE, IPC_CREAT | 0666);        //獲取共享內(nèi)存ID
  if(shm_id < 0)
  {
    perror("shmget");
    exit(0);
  }
  shmp = shmat(shm_id, NULL, 0);        //映像共享內(nèi)存
  if((int)shmp == -1)
  {
    perror("shmat");
    exit(0);
  }
  pid = fork();            //創(chuàng)建子進程
  if(pid < 0)
  {
    perror("fork");
    exit(0);
  }
  else if(pid == 0)        //子進程
  {
    ret = semctl(sme_id, 0, SETVAL, 1);        //初始化信號量,初值設為1
    if(ret == -1)
    {
      perror("semctl");
      exit(0);
    }
    ret = semop(sme_id, &lock, 1);        //申請訪問共享資源,鎖定臨界資源
    if(ret == -1)
    {
      perror("semop lock");
      exit(0);
    }
    sleep(4);            //讓子進程睡眠4秒
    strcpy(shmp, "hello\n");    //往共享內(nèi)存寫入數(shù)據(jù)
    if(shmdt((void *)shmp) < 0)    //使共享內(nèi)存脫離進程地址空間
    {
      perror("shmdt");            
    }
    ret = semop(sme_id, &unlock, 1);        //解鎖臨界資源
    if(ret == -1)
    {
      perror("semop unlock");
      exit(0);
    }
  }
  else                //父進程
  {
    sleep(1);        //先讓子進程運行
    ret = semop(sme_id, &lock, 1);        //申請訪問共享資源,鎖定臨界資源
    if(ret == -1)
    {
      perror("semop lock");
      exit(0);
    }
    if(shmctl(shm_id, IPC_STAT, &dsbuf) < 0)    //獲取共享內(nèi)存信息
    {
      perror("shmctl");
      exit(0);
    }
    else            /* 共享內(nèi)存的狀態(tài)信息獲取成功 */
    {
      printf("Shared Memory Information:\n");
      printf("\tCreator PID: %d\n", dsbuf.shm_cpid);         /* 輸出創(chuàng)建共享內(nèi)存進程的標識符 */
      printf("\tSize(bytes): %d\n",dsbuf.shm_segsz);         /* 輸出共享內(nèi)存的大小 */
      printf("\tLast Operator PID: %d\n",dsbuf.shm_lpid);     /* 輸出上一次操作共享內(nèi)存進程的標識符 */
      printf("Received message : %s\n", (char *)shmp);        /* 從共享內(nèi)存中讀取數(shù)據(jù) */ 
    }
    if(shmdt((void *)shmp) < 0)    //使共享內(nèi)存脫離進程地址空間
    {
      perror("shmdt");
      exit(0);            
    }        
    ret = semop(sme_id, &unlock, 1);        //解鎖臨界資源
    if(ret == -1)
    {
      perror("semop unlock");
      exit(0);
    }
    if(shmctl(shm_id, IPC_RMID, NULL) < 0)    /* 刪除前面創(chuàng)建的共享內(nèi)存 */ 
    {
      perror("shmctl");
      exit(0);            
    }
    ret = semctl(sme_id, 0, IPC_RMID, NULL);    //刪除信號量
    if(ret == -1)
    {        
      perror("semctl");
      exit(0);        
    }
  }    
  return 0;
}

網(wǎng)頁名稱:[Linux管道和IPC]使用信號量和共享內(nèi)存進行父子進程通信
文章URL:http://muchs.cn/article2/pgodoc.html

成都網(wǎng)站建設公司_創(chuàng)新互聯(lián),為您提供自適應網(wǎng)站全網(wǎng)營銷推廣、動態(tài)網(wǎng)站、外貿(mào)建站、網(wǎng)站收錄、面包屑導航

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)

成都做網(wǎng)站