欧美一区二区三区老妇人-欧美做爰猛烈大尺度电-99久久夜色精品国产亚洲a-亚洲福利视频一区二区

Linux中如何共享內(nèi)存

這篇文章給大家分享的是有關(guān)Linux中如何共享內(nèi)存的內(nèi)容。小編覺得挺實(shí)用的,因此分享給大家做個參考,一起跟隨小編過來看看吧。

成都創(chuàng)新互聯(lián)公司是一家集成都網(wǎng)站建設(shè)、網(wǎng)站設(shè)計(jì)、網(wǎng)站頁面設(shè)計(jì)、網(wǎng)站優(yōu)化SEO優(yōu)化為一體的專業(yè)網(wǎng)站建設(shè)公司,已為成都等多地近百家企業(yè)提供網(wǎng)站建設(shè)服務(wù)。追求良好的瀏覽體驗(yàn),以探求精品塑造與理念升華,設(shè)計(jì)最適合用戶的網(wǎng)站頁面。 合作只是第一步,服務(wù)才是根本,我們始終堅(jiān)持講誠信,負(fù)責(zé)任的原則,為您進(jìn)行細(xì)心、貼心、認(rèn)真的服務(wù),與眾多客戶在蓬勃發(fā)展的市場環(huán)境中,互促共生。

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

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

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

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

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

① 進(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)核為每個共享存儲段維護(hù)著一個結(jié)構(gòu),該結(jié)構(gòu)至少要為每個共享存儲段包含以下成員。

struct shmid_ds  {      struct ipc_perm shm_perm;    // 操作權(quán)限       size_t          shm_segsz;   // 段的大小(以字節(jié)為單位)       time_t          shm_atime;   // 上一個進(jìn)程附加到該段的時間       time_t          shm_dtime;   // 上一個進(jìn)程分離開該段的時間      time_t          shm_ctime;   // 上一個進(jìn)程修改該段的時間       pid_t           shm_cpid;    // 創(chuàng)建該段進(jìn)程的PID       pid_t           shm_lpid;    // 上個shmat(2)/shmdt(2)的PID       shmatt_t        shm_nattch;  // 當(dāng)前附加到該段的進(jìn)程的個數(shù)       ... };

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

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

1)shmget函數(shù)

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

① 函數(shù)原型。

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

② 頭文件。

include <sys/ipc.h>   include <sys/shm.h>

③ 參數(shù)。

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

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

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

④ 返回值。

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

失敗:-1。

2)shmat函數(shù)

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

① 函數(shù)原型。

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

② 頭文件。

include <sys/types.h>   include <sys/shm.h>

③ 參數(shù)。

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

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

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

④ 返回值。

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

失敗:-1。

3)shmdt函數(shù)

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

① 函數(shù)原型。

int shmdt(const void *shmaddr)

② 頭文件。

#include <sys/types.h>  #include <sys/shm.h>

③ 參數(shù)。

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

④ 返回值。

成功:0。

失敗:-1。

4)shmctl函數(shù)

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

① 函數(shù)原型。

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

② 頭文件。

#include <sys/ipc.h>  #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),并將它存儲在由buf指向的結(jié)構(gòu)中。

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

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

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

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

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

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

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

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

SHM_UNLOCK:解鎖共享存儲段。

④ 返回值。

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

失敗:-1。

3 實(shí)例代碼

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

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

WriteMemory.c。

#include <sys/types.h> #include <sys/shm.h> #include <sys/ipc.h> #include <stdio.h> #include <unistd.h> #include <stdlib.h> #include <string.h>  #define SIZE 1024                              // 可輸入1K字符串   struct SharedMemoryST {        int ReadWriteFlag;                       // 表明是誰放進(jìn)去的       char CharData[SIZE];                     // 字符數(shù)組保存用戶輸入數(shù)據(jù) };  int main(int argc,char *argv[]) {       int shmid;       int ReadStatusFlag = 1;                 // 內(nèi)存中數(shù)據(jù)是否被讀走,1未被讀走       struct SharedMemoryST *shm;             // 共享內(nèi)存結(jié)構(gòu)變量       char buffer[SIZE];         key_t key=ftok("/tmp",12);              // 創(chuàng)建共享內(nèi)存的鍵值,如果提示創(chuàng)建失敗(一般是沒有quit引起的),可以修改讀寫進(jìn)程的鍵值,都要改成同一數(shù)字        //1 創(chuàng)建共享內(nèi)存       shmid = shmget(key,sizeof(struct SharedMemoryST),IPC_CREAT|IPC_EXCL|0777);       if(shmid == -1)                         // 如果創(chuàng)建失敗       {            printf("\nCreating share memory fail!\n\n");            exit(1);       }        //2 映射共享內(nèi)存       shm = shmat(shmid,NULL,0);              // 內(nèi)存id,映射的位置,映射的標(biāo)志(此無特殊要求)         //3 查詢寫入的       while(ReadStatusFlag)                   // 循環(huán)檢查寫入共享內(nèi)存的數(shù)據(jù)是否被讀走,讀走后退出循環(huán)       {            while(shm->ReadWriteFlag == 1)            {                 sleep(1);                 printf("\nWaiting read memory!\n");            }               // 獲取用戶輸入            printf("\nPlease input data or input 'quit' to exit!\n\n");            fgets(buffer,SIZE,stdin);          // 參數(shù):字符串的位置,長度,獲取的方式位置               // 將用戶輸入的字符串放入共享內(nèi)存            strncpy(shm->CharData,buffer,SIZE);// 參數(shù):目的數(shù)據(jù),源數(shù)據(jù),數(shù)據(jù)大小               shm->ReadWriteFlag = 1;             if(strncmp(buffer,"quit",4) == 0)  // 最后一個參數(shù)為比較字符的數(shù)量            {                 ReadStatusFlag = 0;           // 寫入共享內(nèi)存的數(shù)據(jù)已經(jīng)被讀走            }        }        //4 脫離共享存       shmdt((const void *)shm);        return 0;                }

ReadMemory.c。

#include <sys/types.h> #include <sys/shm.h> #include <sys/ipc.h> #include <stdio.h> #include <unistd.h> #include <stdlib.h>  #define SIZE 1024                        // 可輸入1K字符串  struct SharedMemoryST {      int ReadWriteFlag;                  // 標(biāo)明是讀進(jìn)程還是寫進(jìn)程放入了數(shù)據(jù)      char CharData[SIZE];                // 保存用戶輸入數(shù)據(jù) };  int main(int argc,char *argv[]) {      int shmid;      int ReadStatusFlag = 1;            // 內(nèi)存中數(shù)據(jù)是否被讀走的標(biāo)志位,1表示未被讀走      struct SharedMemoryST *shm;        // 共享內(nèi)存結(jié)構(gòu)         key_t key=ftok("/tmp",12);         // 創(chuàng)建共享內(nèi)存的鍵值,如果提示創(chuàng)建失敗,修改一下數(shù)字即可,讀寫進(jìn)程都要改成同一數(shù)字           //1 創(chuàng)建/獲取共享內(nèi)存      shmid = shmget(key,sizeof(struct SharedMemoryST),IPC_CREAT|0777);//分配大小為結(jié)構(gòu)大小,1234是隨便給的鍵值       //2 映射共享內(nèi)存      shm = (struct SharedMemoryST *)shmat(shmid,NULL,0);              //內(nèi)存id,映射的位置,映射的標(biāo)志(此無特殊要求)       shm->ReadWriteFlag = 0;       //3 檢查是否收到信息,收到quit退出      while(ReadStatusFlag)      {           //打印共享內(nèi)存          if(shm->ReadWriteFlag == 1)    // 等于說明有相應(yīng)的數(shù)據(jù)          {                printf("\nThe write context is: %s\n",shm->CharData);               shm->ReadWriteFlag = 0;                      if(strncmp(shm->CharData,"quit",3) == 0)               {                     ReadStatusFlag = 0; // 結(jié)束查詢,退出               }          }      }       //4 脫離共享內(nèi)存      shmdt((const void *)shm);       //5 刪除共享內(nèi)存      shmctl(shmid,IPC_RMID,0); }

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

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

Linux中如何共享內(nèi)存

感謝各位的閱讀!關(guān)于“Linux中如何共享內(nèi)存”這篇文章就分享到這里了,希望以上內(nèi)容可以對大家有一定的幫助,讓大家可以學(xué)到更多知識,如果覺得文章不錯,可以把它分享出去讓更多的人看到吧!

本文題目:Linux中如何共享內(nèi)存
URL網(wǎng)址:http://chinadenli.net/article40/jgjjeo.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供手機(jī)網(wǎng)站建設(shè)關(guān)鍵詞優(yōu)化定制開發(fā)營銷型網(wǎng)站建設(shè)外貿(mào)網(wǎng)站建設(shè)

廣告

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

手機(jī)網(wǎng)站建設(shè)