自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

Linux下的共享內(nèi)存編程

系統(tǒng) Linux
前面帶小伙伴們學(xué)習(xí)了共享內(nèi)存相關(guān)的內(nèi)容,先簡(jiǎn)單介紹下共享內(nèi)存,然后進(jìn)行結(jié)構(gòu)及函數(shù)的學(xué)習(xí),最后擼代碼使用一下這些函數(shù)使用一下共享內(nèi)存,希望對(duì)大家有所幫助哈!

[[385298]]

前面帶小伙伴們學(xué)習(xí)了共享內(nèi)存相關(guān)的內(nèi)容,先簡(jiǎn)單介紹下共享內(nèi)存,然后進(jìn)行結(jié)構(gòu)及函數(shù)的學(xué)習(xí),最后擼代碼使用一下這些函數(shù)使用一下共享內(nèi)存,希望對(duì)大家有所幫助哈! 

 

1 共享內(nèi)存的概念及使用過(guò)程

1)共享內(nèi)存的概念

共享內(nèi)存是IPC機(jī)制中的一種。

共享內(nèi)存:即允許兩個(gè)或多個(gè)進(jìn)程共享一個(gè)給定的存儲(chǔ)區(qū)。

2)共享內(nèi)存的使用過(guò)程

① 進(jìn)程1創(chuàng)建共享內(nèi)存,接著映射共享內(nèi)存。

② 進(jìn)程2獲取共享內(nèi)存,映射共享內(nèi)存。

③ 交互完成,進(jìn)程1分離共享內(nèi)存,進(jìn)程2分離共享內(nèi)存。

④ 進(jìn)程1刪除共享內(nèi)存。

2 共享內(nèi)存相關(guān)的結(jié)構(gòu)及函數(shù)

0)共享內(nèi)存相關(guān)的結(jié)構(gòu)

內(nèi)核為每個(gè)共享存儲(chǔ)段維護(hù)著一個(gè)結(jié)構(gòu),該結(jié)構(gòu)至少要為每個(gè)共享存儲(chǔ)段包含以下成員。

  1. struct shmid_ds  
  2.      struct ipc_perm shm_perm;    // 操作權(quán)限  
  3.      size_t          shm_segsz;   // 段的大?。ㄒ宰止?jié)為單位)  
  4.      time_t          shm_atime;   // 上一個(gè)進(jìn)程附加到該段的時(shí)間  
  5.      time_t          shm_dtime;   // 上一個(gè)進(jìn)程分離開該段的時(shí)間 
  6.      time_t          shm_ctime;   // 上一個(gè)進(jìn)程修改該段的時(shí)間  
  7.      pid_t           shm_cpid;    // 創(chuàng)建該段進(jìn)程的PID  
  8.      pid_t           shm_lpid;    // 上個(gè)shmat(2)/shmdt(2)的PID  
  9.      shmatt_t        shm_nattch;  // 當(dāng)前附加到該段的進(jìn)程的個(gè)數(shù)  
  10.      ... 
  11. }; 

系統(tǒng)為每一個(gè)IPC對(duì)象保存一個(gè)ipc_perm結(jié)構(gòu)體,該結(jié)構(gòu)說(shuō)明了IPC對(duì)象的權(quán)限和所有者,每一個(gè)版本的內(nèi)核各有不用的ipc_perm結(jié)構(gòu)成員。

  1. struct ipc_perm  
  2.      key_t          __key;    // 為 shmget(2) 調(diào)用提供的鍵值 
  3.      uid_t          uid;      // 共享內(nèi)存所有者的有效用戶UID  
  4.      gid_t          gid;      // 共享內(nèi)存所有者所屬組的有效組GID  
  5.      uid_t          cuid;     // 共享內(nèi)存創(chuàng)建者的有效用戶UID  
  6.      gid_t          cgid;     // 共享內(nèi)存創(chuàng)建者所屬組的有效組ID  
  7.      unsigned short mode;     // 特權(quán) + SHM_DEST 和SHM_LOCKED 標(biāo)志  
  8.      unsigned short __seq;    // 序列號(hào) 
  9. }; 

1)shmget函數(shù)

shmget函數(shù)用于創(chuàng)建或者獲取共享內(nèi)存,并返回其描述符id。

① 函數(shù)原型。

  1. int shmget(key_t key,size_t sizie,int shmflg) 

② 頭文件。

  1. include <sys/ipc.h>  
  2.  
  3. include <sys/shm.h>  

③ 參數(shù)。

key:共享內(nèi)存的鍵值。

size:共享內(nèi)存的大小。

shmflg:打開標(biāo)志,如果使用了IPC_CREAT,則會(huì)新創(chuàng)建一塊共享內(nèi)存。

④ 返回值。

成功:返回創(chuàng)建或者獲取到的共享內(nèi)存的描述符。

失?。?1。

2)shmat函數(shù)

shmat函數(shù)用于映射共享內(nèi)存,即將進(jìn)程連接到它的地址空間。

① 函數(shù)原型。

  1. void *shmat(int shmid,const void *shmaddr,int shmflg) 

② 頭文件。

  1. include <sys/types.h>  
  2.  
  3. include <sys/shm.h>  

③ 參數(shù)。

shmid:要映射的共享內(nèi)存的描述符。

shmaddr:共享內(nèi)存的地址。

shmflg:打開標(biāo)志,如果使用了IPC_CREAT,則會(huì)新創(chuàng)建一塊共享內(nèi)存。

④ 返回值。

成功:返回創(chuàng)建或者獲取到的共享內(nèi)存的描述符。

失?。?1。

3)shmdt函數(shù)

shmdt函數(shù)用于分離共享內(nèi)存,即操作完存儲(chǔ)段后,用此函數(shù)可以將進(jìn)程與此存儲(chǔ)段脫離開,即斷掉與共享內(nèi)存的聯(lián)系。

① 函數(shù)原型。

  1. int shmdt(const void *shmaddr) 

② 頭文件。

  1. #include <sys/types.h> 
  2.  
  3. #include <sys/shm.h>  

③ 參數(shù)。

shmaddr:要斷開的共享內(nèi)存的映射地址。

④ 返回值。

成功:0。

失敗:-1。

4)shmctl函數(shù)

shmctl函數(shù)用于控制共享內(nèi)存,通過(guò)參數(shù)可以對(duì)共享內(nèi)存進(jìn)行特定的操作。

① 函數(shù)原型。

  1. int shmctl(int shmid, int cmd, struct shmid_ds *buf) 

② 頭文件。

  1. #include <sys/ipc.h> 
  2.  
  3. #include <sys/shm.h>  

③ 參數(shù)。

shmid:要控制的共享內(nèi)存的id。

cmd:決定執(zhí)行什么樣的控制操作,如IPC_RMID(表示刪除)。

buf:獲取linux中描述共享內(nèi)存的shmid_ds結(jié)構(gòu)。基本不使用。

cmd可去的參數(shù)如下,需要參照上面的結(jié)構(gòu)shmid_ds和ipc_perm :

IPC_STAT:取此段的shmid_ds結(jié)構(gòu),并將它存儲(chǔ)在由buf指向的結(jié)構(gòu)中。

IPC_SET:按buf指向的結(jié)構(gòu)中的值設(shè)置與此共享存儲(chǔ)段相關(guān)的shmid_ds結(jié)構(gòu)中的下列3個(gè)字段:shmperm.uid、shm perm.gid和shmperm.mode。

此命令只能由下列兩種進(jìn)程執(zhí)行:一種是其有效用戶ID等于shm_perm.cuid或shmperm.uid的進(jìn)程;另一種是具有超級(jí)用戶特權(quán)的進(jìn)程。

IPC_RMID:從系統(tǒng)中刪除該共享存儲(chǔ)段。

除非使用該段的最后一個(gè)進(jìn)程終止或與該段分離,否則不會(huì)實(shí)際上刪除該存儲(chǔ)段。

不管此段是否仍在使用,該段標(biāo)識(shí)符都會(huì)被立即刪除,所以不能再用shmat與該段連接。

此命令只能由下列兩種進(jìn)程執(zhí)行:一種是其有效用戶ID等于shm_perm.cuid或shm_perm.uid的進(jìn)程;另一種是具有超級(jí)用戶特權(quán)的進(jìn)程。

下面兩個(gè)命令只能由超級(jí)用戶執(zhí)行:

SHM_LOCK:在內(nèi)存中對(duì)共享存儲(chǔ)段加鎖。

SHM_UNLOCK:解鎖共享存儲(chǔ)段。

④ 返回值。

成功:根據(jù)不同的操作返回不同的值。

失?。?1。

3 實(shí)例代碼

下面用兩個(gè)進(jìn)程,給大家演示下共享內(nèi)存的使用過(guò)程。

實(shí)例代碼如下,說(shuō)明都在代碼注釋中了。

 

WriteMemory.c。

  1. #include <sys/types.h> 
  2. #include <sys/shm.h> 
  3. #include <sys/ipc.h> 
  4. #include <stdio.h> 
  5. #include <unistd.h> 
  6. #include <stdlib.h> 
  7. #include <string.h> 
  8.  
  9. #define SIZE 1024                              // 可輸入1K字符串 
  10.  
  11.  
  12. struct SharedMemoryST 
  13. {  
  14.       int ReadWriteFlag;                       // 表明是誰(shuí)放進(jìn)去的 
  15.       char CharData[SIZE];                     // 字符數(shù)組保存用戶輸入數(shù)據(jù) 
  16. }; 
  17.  
  18. int main(int argc,char *argv[]) 
  19.       int shmid; 
  20.       int ReadStatusFlag = 1;                 // 內(nèi)存中數(shù)據(jù)是否被讀走,1未被讀走 
  21.       struct SharedMemoryST *shm;             // 共享內(nèi)存結(jié)構(gòu)變量 
  22.       char buffer[SIZE]; 
  23.   
  24.       key_t key=ftok("/tmp",12);              // 創(chuàng)建共享內(nèi)存的鍵值,如果提示創(chuàng)建失敗(一般是沒(méi)有quit引起的),可以修改讀寫進(jìn)程的鍵值,都要改成同一數(shù)字 
  25.  
  26.       //1 創(chuàng)建共享內(nèi)存 
  27.       shmid = shmget(key,sizeof(struct SharedMemoryST),IPC_CREAT|IPC_EXCL|0777); 
  28.       if(shmid == -1)                         // 如果創(chuàng)建失敗 
  29.       { 
  30.            printf("\nCreating share memory fail!\n\n"); 
  31.            exit(1); 
  32.       } 
  33.  
  34.       //2 映射共享內(nèi)存 
  35.       shm = shmat(shmid,NULL,0);              // 內(nèi)存id,映射的位置,映射的標(biāo)志(此無(wú)特殊要求) 
  36.  
  37.  
  38.       //3 查詢寫入的 
  39.       while(ReadStatusFlag)                   // 循環(huán)檢查寫入共享內(nèi)存的數(shù)據(jù)是否被讀走,讀走后退出循環(huán) 
  40.       { 
  41.            while(shm->ReadWriteFlag == 1) 
  42.            { 
  43.                 sleep(1); 
  44.                 printf("\nWaiting read memory!\n"); 
  45.            } 
  46.    
  47.            // 獲取用戶輸入 
  48.            printf("\nPlease input data or input 'quit' to exit!\n\n"); 
  49.            fgets(buffer,SIZE,stdin);          // 參數(shù):字符串的位置,長(zhǎng)度,獲取的方式位置 
  50.    
  51.            // 將用戶輸入的字符串放入共享內(nèi)存 
  52.            strncpy(shm->CharData,buffer,SIZE);// 參數(shù):目的數(shù)據(jù),源數(shù)據(jù),數(shù)據(jù)大小 
  53.    
  54.            shm->ReadWriteFlag = 1; 
  55.  
  56.            if(strncmp(buffer,"quit",4) == 0)  // 最后一個(gè)參數(shù)為比較字符的數(shù)量 
  57.            { 
  58.                 ReadStatusFlag = 0;           // 寫入共享內(nèi)存的數(shù)據(jù)已經(jīng)被讀走 
  59.            } 
  60.  
  61.       } 
  62.  
  63.       //4 脫離共享存 
  64.       shmdt((const void *)shm); 
  65.  
  66.       return 0;                

ReadMemory.c。

  1. #include <sys/types.h> 
  2. #include <sys/shm.h> 
  3. #include <sys/ipc.h> 
  4. #include <stdio.h> 
  5. #include <unistd.h> 
  6. #include <stdlib.h> 
  7.  
  8. #define SIZE 1024                        // 可輸入1K字符串 
  9.  
  10. struct SharedMemoryST 
  11.      int ReadWriteFlag;                  // 標(biāo)明是讀進(jìn)程還是寫進(jìn)程放入了數(shù)據(jù) 
  12.      char CharData[SIZE];                // 保存用戶輸入數(shù)據(jù) 
  13. }; 
  14.  
  15. int main(int argc,char *argv[]) 
  16.      int shmid; 
  17.      int ReadStatusFlag = 1;            // 內(nèi)存中數(shù)據(jù)是否被讀走的標(biāo)志位,1表示未被讀走 
  18.      struct SharedMemoryST *shm;        // 共享內(nèi)存結(jié)構(gòu) 
  19.    
  20.      key_t key=ftok("/tmp",12);         // 創(chuàng)建共享內(nèi)存的鍵值,如果提示創(chuàng)建失敗,修改一下數(shù)字即可,讀寫進(jìn)程都要改成同一數(shù)字 
  21.   
  22.    
  23.      //1 創(chuàng)建/獲取共享內(nèi)存 
  24.      shmid = shmget(key,sizeof(struct SharedMemoryST),IPC_CREAT|0777);//分配大小為結(jié)構(gòu)大小,1234是隨便給的鍵值 
  25.  
  26.      //2 映射共享內(nèi)存 
  27.      shm = (struct SharedMemoryST *)shmat(shmid,NULL,0);              //內(nèi)存id,映射的位置,映射的標(biāo)志(此無(wú)特殊要求) 
  28.  
  29.      shm->ReadWriteFlag = 0; 
  30.  
  31.      //3 檢查是否收到信息,收到quit退出 
  32.      while(ReadStatusFlag) 
  33.      { 
  34.           //打印共享內(nèi)存 
  35.          if(shm->ReadWriteFlag == 1)    // 等于說(shuō)明有相應(yīng)的數(shù)據(jù) 
  36.          {  
  37.               printf("\nThe write context is: %s\n",shm->CharData); 
  38.               shm->ReadWriteFlag = 0; 
  39.        
  40.               if(strncmp(shm->CharData,"quit",3) == 0) 
  41.               { 
  42.                     ReadStatusFlag = 0; // 結(jié)束查詢,退出 
  43.               } 
  44.          } 
  45.      } 
  46.  
  47.      //4 脫離共享內(nèi)存 
  48.      shmdt((const void *)shm); 
  49.  
  50.      //5 刪除共享內(nèi)存 
  51.      shmctl(shmid,IPC_RMID,0); 

寫共享內(nèi)存先創(chuàng)建共享內(nèi)存,寫入數(shù)據(jù),讀共享內(nèi)存讀取數(shù)據(jù),通過(guò)標(biāo)志查詢方式,退出輸入quit。

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

本文轉(zhuǎn)載自微信公眾號(hào)「嵌入式雜牌軍」,可以通過(guò)以下二維碼關(guān)注。轉(zhuǎn)載本文請(qǐng)聯(lián)系嵌入式雜牌軍公眾號(hào)。

 

責(zé)任編輯:武曉燕 來(lái)源: 嵌入式雜牌軍
相關(guān)推薦

2020-10-09 07:13:11

Linux系統(tǒng)編程mmap

2019-05-08 11:10:05

Linux進(jìn)程語(yǔ)言

2009-12-14 17:13:04

Linux系統(tǒng)修改共享

2018-01-12 14:35:00

Linux進(jìn)程共享內(nèi)存

2017-08-14 13:35:36

Linux共享內(nèi)存tmpfs文件系統(tǒng)

2013-11-26 16:05:24

Linux共享內(nèi)存

2021-10-06 20:23:08

Linux共享內(nèi)存

2021-03-08 08:55:41

Linux內(nèi)存命令

2022-06-07 12:03:33

Java內(nèi)存模型

2023-07-06 00:45:05

Linux保護(hù)模式

2009-04-24 10:57:25

2009-08-08 09:50:30

Linux操作系統(tǒng)共享內(nèi)存Linux

2010-06-11 11:15:33

Linux編程工具

2013-04-09 14:49:18

Linux內(nèi)存統(tǒng)計(jì)內(nèi)存泄露

2025-03-26 00:00:05

2010-09-27 15:03:34

TomcatJVM內(nèi)存設(shè)置

2025-04-27 03:22:00

2017-04-13 13:00:27

LinuxWindowstomcat

2009-04-24 14:56:24

2020-11-06 18:51:17

LinuxTCP服務(wù)器
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)