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

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

網(wǎng)站建設(shè) 天津國內(nèi)軍事新聞最新消息

網(wǎng)站建設(shè) 天津,國內(nèi)軍事新聞最新消息,安論壇網(wǎng)站建設(shè),wordpress默認(rèn)域名system V一、system V介紹二 、共享內(nèi)存2.1 共享內(nèi)存的原理2.2 共享內(nèi)存接口2.2.1 創(chuàng)建共享內(nèi)存shmget2.2.2 查看IPC資源2.2.3 共享內(nèi)存的控制shmctl2.2.4 共享內(nèi)存的關(guān)聯(lián)shmat2.2.5 共享內(nèi)存的去關(guān)聯(lián)shmdt2.3 進程間通信2.4 共享內(nèi)存的特性2.5 共享內(nèi)存的大小三、消息隊列3.1 …

system V

  • 一、system V介紹
  • 二 、共享內(nèi)存
    • 2.1 共享內(nèi)存的原理
    • 2.2 共享內(nèi)存接口
      • 2.2.1 創(chuàng)建共享內(nèi)存shmget
      • 2.2.2 查看IPC資源
      • 2.2.3 共享內(nèi)存的控制shmctl
      • 2.2.4 共享內(nèi)存的關(guān)聯(lián)shmat
      • 2.2.5 共享內(nèi)存的去關(guān)聯(lián)shmdt
    • 2.3 進程間通信
    • 2.4 共享內(nèi)存的特性
    • 2.5 共享內(nèi)存的大小
  • 三、消息隊列
    • 3.1 消息隊列的概念
    • 3.2 消息隊列接口
      • 3.2.1 消息隊列的獲取msgget
      • 3.2.2 消息隊列的控制msgctl
      • 3.2.3 消息隊列發(fā)送數(shù)據(jù)msgsnd
      • 3.2.4 消息隊列獲取msgrcv
  • 四、信號量
    • 4.1 信號量概念
    • 4.2 信號量的用處
    • 4.3 信號量的pv操作
    • 4.4 信號量接口
      • 4.4.1 信號量申請semget
      • 4.4.2 信號量控制semctl
      • 4.4.3 信號量操作semop
  • 五、總結(jié)

一、system V介紹

進程間通信除了通過管道,都是基于文件的通信方式,還有一種方式是:SystemV標(biāo)準(zhǔn)的進程間通信方式。SystemV是一個在OS層面專門為進程通信設(shè)計的一個方案。這些都是由計算機科學(xué)家和程序員設(shè)計的,并且需要給用戶使用。

如果要給用戶用,是以什么方式給用戶使用的呢?在操作系統(tǒng)層面上,SystemV是OS內(nèi)核的一部分,是為OS中多進程提供的一種通信方案。但是OS不相信任何用戶,給用戶提供功能的時候,采用系統(tǒng)調(diào)用。所以System V進程間通信,一定會存在專門用來通信的接口:system call。

因為在早期由很多的方案,但是我們需要統(tǒng)一使用一個方案,所以現(xiàn)在誕生了在統(tǒng)一主機內(nèi)的進程間通信方案:system V方案。

system V IPC提供的通信方式有三種: 共享內(nèi)存、消息隊列、信號量

二 、共享內(nèi)存

2.1 共享內(nèi)存的原理

前面說過兩個進程要通信就需要看到同一塊資源。

而我們知道進程之間具有獨立性,物理內(nèi)存當(dāng)中代碼和數(shù)據(jù)也互相獨立。
那么現(xiàn)在我們可以在物理內(nèi)存中創(chuàng)建一個內(nèi)存塊,讓不同的進程都能看到這個內(nèi)存塊,具體的做法如下:

1?? 通過某種調(diào)用,在內(nèi)存中創(chuàng)建一份內(nèi)存空間。
2?? 通過某種調(diào)用,讓進程”掛接“到這份內(nèi)存空間上。(將創(chuàng)建好的內(nèi)存映射進進程地址空間)
在后面可能不會共享內(nèi)存了。所以在不用共享內(nèi)存的時候
3?? 去關(guān)聯(lián)(去掛接)。
4?? 釋放共享內(nèi)存。

對于共享內(nèi)存的理解:
OS內(nèi)可能存在多個進程同時使用不同的共享內(nèi)存來進行進程間通信,既然有多份共享內(nèi)存,那么操作系統(tǒng)就要管理它們,按照前面學(xué)習(xí)的經(jīng)驗,先描述后組織,描述就是對共享內(nèi)存的一系列屬性進行描述,而后用數(shù)據(jù)結(jié)構(gòu)組織起來,這樣對共享內(nèi)存的管理變成了對數(shù)據(jù)結(jié)構(gòu)的操作。

2.2 共享內(nèi)存接口

2.2.1 創(chuàng)建共享內(nèi)存shmget

shmget:用來創(chuàng)建共享內(nèi)存

 #include <sys/ipc.h>#include <sys/shm.h>int shmget(key_t key, size_t size, int shmflg);RETURN VALUEOn success, a valid shared memory identifier is returned.  On errir, -1 is returned, and errno is set to indicate the error.

參數(shù)說明:

size:共享內(nèi)存的大小。
shmflag:通常有兩種選項:IPC_CREAT、IPC_EXCL。
IPC_CREAT: 共享內(nèi)存如果不存在,則創(chuàng)建,不存在則獲取。
IPC_EXCL: 無法單獨使用
IPC_CREAT | IPC_EXCL: 如果不存在就創(chuàng)建,如果存在就出錯返回(保證共享內(nèi)存是新創(chuàng)建的)。
如果shmflag是0默認(rèn)就是IPC_CREAT。
key:保證看到同一份共享內(nèi)存,能進行唯一性標(biāo)識(就像省份證號碼一樣,數(shù)字不重要,只用來標(biāo)識唯一性)。通過ftok函數(shù)轉(zhuǎn)化。
如果創(chuàng)建成功返回共享內(nèi)存的標(biāo)識符,如果失敗則返回-1。

ftok:用來形成key

#include <sys/types.h>
#include <sys/ipc.h>key_t ftok(const char *pathname, int proj_id);
RETURN VALUE
On success, the generated key_t value is returned.  
On failure -1 is returned, with errno indicating the error as for the stat(2) system call.

ftok第一個參數(shù)是自定義路徑名,第二個參數(shù)是自定義的項目ID。最后唯一的共享內(nèi)存ID就是通過路徑名+項目ID來標(biāo)識。最后生成的返回值并不重要,只要它能生成一個值來唯一標(biāo)識這塊共享內(nèi)存就可以。
只要參數(shù)不變,生成的返回值就不會變。 這樣就可以讓兩個進程擁有同一個key,就可以用key找到同一份共享內(nèi)存。

key_t GetKey()
{key_t n = ftok(PATHNAME, PROJ_ID);if(n == -1){std::cerr << errno << ":" << strerror(errno) << std::endl;assert(false);}return n;
}int Creatshm(key_t key)
{int shmid = shmget(key, SIZE, IPC_CREAT | IPC_EXCL | 0666);if(shmid == -1){std::cerr << errno << ":" << strerror(errno) << std::endl;assert(false);}return shmid;
}int Getshm(key_t key)
{int shmid = shmget(key, SIZE, IPC_CREAT | 0666);if(shmid == -1){std::cerr << errno << ":" << strerror(errno) << std::endl;assert(false);}return shmid;
}

key的理解:
上面也說過了OS會把內(nèi)存塊管理起來,共享內(nèi)存=物理內(nèi)存塊+共享內(nèi)存的相關(guān)屬性描述共享內(nèi)存時就有一個字段struct shm中有key。 一個進程創(chuàng)建內(nèi)存塊后把key值寫進相關(guān)屬性中,而另一個進程拿著key值遍歷相關(guān)屬性查找。這樣就完成了兩個進程共享一塊內(nèi)存塊。
我們發(fā)現(xiàn)key和shmid都是標(biāo)識內(nèi)存塊的:key是在內(nèi)核標(biāo)識唯一性,而shmid是在用戶層標(biāo)識唯一性,這樣即使操作系統(tǒng)有什么變化也不會影響用戶使用,充分的解耦。他們的關(guān)系就類似于fd與inode。

2.2.2 查看IPC資源

共享內(nèi)存的生命周期不是隨著進程的,而是隨著OS的,這也是所有system V進程間通信的特征。

ipcs -m 查看共享內(nèi)存
在這里插入圖片描述
ipcs -q 查看消息隊列
ipcs -s 查看信號量
在這里插入圖片描述

ipcs 三個一起查看
在這里插入圖片描述
ipcrm -m shmid 刪除共享內(nèi)存
在這里插入圖片描述

2.2.3 共享內(nèi)存的控制shmctl

shmctl:控制共享內(nèi)存

#include <sys/ipc.h>
#include <sys/shm.h>int shmctl(int shmid, int cmd, struct shmid_ds *buf);

它的作用是對共享內(nèi)存的控制。
參數(shù)介紹:
shmid:控制共享內(nèi)存的標(biāo)識符。
cmd:控制的種類,主要用的是IPC_RMID(立即移除共享內(nèi)存)。
buf:控制共享內(nèi)存的數(shù)據(jù)結(jié)構(gòu),設(shè)置為空即可。
返回值:0表示返回成功,-1表示失敗。

void Delshm(int shmid)
{if(shmctl(shmid, IPC_RMID, nullptr) == -1){std::cerr << errno << ":" << strerror(errno) << std::endl;assert(false);}
}

2.2.4 共享內(nèi)存的關(guān)聯(lián)shmat

#include <sys/types.h>
#include <sys/shm.h>void *shmat(int shmid, const void *shmaddr, int shmflg);

參數(shù)介紹:
shmaddr:可以指定虛擬內(nèi)存,設(shè)置為nullptr即可。
shmflg:讀取權(quán)限,默認(rèn)為0。
返回值:返回共享內(nèi)存的起始地址。

void* Attachshm(int shmid)
{void* mem = shmat(shmid, nullptr, 0);if((long long)mem == -1L)// 64位指針8字節(jié){std::cerr << errno << ":" << strerror(errno) << std::endl;assert(false);}return mem;
}

2.2.5 共享內(nèi)存的去關(guān)聯(lián)shmdt

去關(guān)聯(lián)是指把進程和共享內(nèi)存之間的映射關(guān)系刪掉(修改頁表),并不是刪除共享內(nèi)存。

#include <sys/types.h>
#include <sys/shm.h>int shmdt(const void *shmaddr);

它的參數(shù)就是在shmat返回的參數(shù)。
成功返回0,失敗返回-1。

void Detachshm(void* start)
{if(shmdt(start) == -1){std::cerr << errno << ":" << strerror(errno) << std::endl;assert(false);}
}

2.3 進程間通信

comm.hpp

#ifndef _COMM_HPP_
#define _COMM_HPP_#include <iostream>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <cstring>
#include <cerrno>
#include <cassert>
#include <cstdlib>
#include <cstdio>
#include <unistd.h>#define PATHNAME ".."
#define PROJ_ID 12345
#define SIZE 4096key_t GetKey()
{key_t n = ftok(PATHNAME, PROJ_ID);if(n == -1){std::cerr << errno << ":" << strerror(errno) << std::endl;assert(false);}return n;
}int Creatshm(key_t key)
{int shmid = shmget(key, SIZE, IPC_CREAT | IPC_EXCL | 0666);if(shmid == -1){std::cerr << errno << ":" << strerror(errno) << std::endl;assert(false);}return shmid;
}int Getshm(key_t key)
{int shmid = shmget(key, SIZE, IPC_CREAT | 0666);if(shmid == -1){std::cerr << errno << ":" << strerror(errno) << std::endl;assert(false);}return shmid;
}void Delshm(int shmid)
{if(shmctl(shmid, IPC_RMID, nullptr) == -1){std::cerr << errno << ":" << strerror(errno) << std::endl;assert(false);}
}void* Attachshm(int shmid)
{void* mem = shmat(shmid, nullptr, 0);if((long long)mem == -1L)// 64位指針8字節(jié){std::cerr << errno << ":" << strerror(errno) << std::endl;assert(false);}return mem;
}void Detachshm(void* start)
{if(shmdt(start) == -1){std::cerr << errno << ":" << strerror(errno) << std::endl;assert(false);}
}#endif

shm_a.cc

#include "comm.hpp"int main()
{key_t k = GetKey();// 創(chuàng)建共享內(nèi)存int shmid = Creatshm(k);// 掛接char* start = (char*)Attachshm(shmid);//使用while(true){if(strlen(start) > 4){printf("%s\n", start);}if(strlen(start) == 4){break;}sleep(1);}// 去關(guān)聯(lián)Detachshm(start);// 刪除共享內(nèi)存Delshm(shmid);return 0;
}

shm_b.cc

#include "comm.hpp"int main()
{key_t k = GetKey();// 獲取共享內(nèi)存int shmid = Getshm(k);// 掛接char* start = (char*)Attachshm(shmid);// 使用std::string str = "hello shm";int cnt = 0;while(cnt != 8){snprintf(start, SIZE, "%s[%d]", str.c_str(),  cnt);cnt++;sleep(1);}std::string cmd = "stop";snprintf(start, SIZE, "%s", cmd.c_str());// 去關(guān)聯(lián)Detachshm(start);return 0;
}

2.4 共享內(nèi)存的特性

1?? 共享內(nèi)存是所有的進程間通信速度最快的。(優(yōu)點)
2?? 共享內(nèi)存不提供任何同步或者互斥機制,不提供不代表不需要,所以需要程序員自行保證數(shù)據(jù)的安全!這也造成了共享內(nèi)存在多進程中是不太安全的。(缺點)
3?? 共享內(nèi)存的生命周期是隨OS的,而不是隨進程的,這是所有System V進程間通信的共性。

為什么速度快呢?
管道和共享內(nèi)存:考慮鍵盤輸入,和顯示器輸出,對于同一份數(shù)據(jù),共享內(nèi)存有幾次數(shù)據(jù)拷貝,管道有幾次數(shù)據(jù)拷貝

管道:在這里插入圖片描述
可以看到寫到管道需要拷貝兩次,而另一個進程讀也需要兩次,所以一共四次。如果考慮到輸入輸出外設(shè),那么就是六次。

共享內(nèi)存:
直接寫入共享內(nèi)存,直接從共享內(nèi)存輸出,所以是兩次??紤]到輸入輸出的話就是四次。

2.5 共享內(nèi)存的大小

這里講的是shget的第二個參數(shù),一般建議設(shè)置成4096(4KB)的整數(shù)倍,因為系統(tǒng)分享內(nèi)存是以4KB為單位,假如我們申請的是4097,那么系統(tǒng)就會直接向上取整,也就是4096*2,但是我們只能使用其中的4097大小。

三、消息隊列

3.1 消息隊列的概念

消息隊列提供了一個從一個進程向另外一個進程發(fā)送一塊數(shù)據(jù)的方法,讀端和寫端公用一個隊列,每個數(shù)據(jù)塊就是隊列的一個節(jié)點,每個數(shù)據(jù)塊都會有個記錄類型的數(shù)據(jù),來判斷該數(shù)據(jù)塊該被哪個進程讀取。

3.2 消息隊列接口

3.2.1 消息隊列的獲取msgget

#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>int msgget(key_t key, int msgflg);

這里的msgflg跟共享內(nèi)存的兩個參數(shù)一摸一樣(IPC_CREAT、IPC_EXCL)。

返回值:msgget函數(shù)返回的一個有效的消息隊列標(biāo)識符

3.2.2 消息隊列的控制msgctl

#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>int msgctl(int msqid, int cmd, struct msqid_ds *buf);

參數(shù)說明:
msqid:消息隊列的標(biāo)識符。
其他的參數(shù)跟shmctl一樣。

3.2.3 消息隊列發(fā)送數(shù)據(jù)msgsnd

#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
int msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg);

參數(shù)說明:
msqid:消息隊列的用戶級標(biāo)識符。
msgp:表示待發(fā)送的數(shù)據(jù)塊(輸出型參數(shù))。
在這里插入圖片描述

msgsz:表示所發(fā)送數(shù)據(jù)塊的大小
msgflg:表示發(fā)送數(shù)據(jù)塊的方式,一般默認(rèn)為0即可
成功返回0,失敗返回-1

3.2.4 消息隊列獲取msgrcv

#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
ssize_t msgrcv(int msqid, void *msgp, size_t msgsz, long msgtyp,int msgflg)

參數(shù)跟上面msgsnd一致。

四、信號量

4.1 信號量概念

信號量本質(zhì)上就是個計數(shù)器,它統(tǒng)計的是公共資源資源還剩多少。

公共資源:可以被多個進程同時訪問的資源,而如果訪問沒有被保護的公共資源,就會導(dǎo)致數(shù)據(jù)不一致問題(一個進程還在寫的時候另一個進程就開始讀)。所以公共資源需要保護,被保護起來的資源稱為臨界資源。而訪問這些臨界資源的那部分代碼稱為臨界區(qū)。其他的代碼就稱為非臨界區(qū)。

保護公共資源:同步和互斥

互斥:當(dāng)有多個進程想要訪問同一份資源的時候,我們只允許一個進程訪問,當(dāng)這個進程訪問完了,下一個進程才能訪問。

原子性:要么不做,要么做完,只有這兩種狀態(tài)的情況。

既然我們想讓多個進程看到同一個計數(shù)器,那么信號量也是個公共資源

4.2 信號量的用處

舉個例子,假設(shè)我們要去看電影,而里面的座位只有我們買了票才能擁有,這里的票就是信號量,我們買了一張后,信號量就--。

所以當(dāng)我們想要某種資源的時候,我們可以進行預(yù)定(買票成功)。
共享資源可以作為一個整體使用或者劃分成多個子資源部分。大部分都是整體使用,比如果管道。

如果我們申請成功,相當(dāng)于我們預(yù)定了共享內(nèi)存中的一小部分資源。如果不成功,就不能訪問共享資源,以達(dá)到保護其他進程的目的。

在訪問公共資源前要先申請信號量,而信號量本身就是個公共資源,那么信號量也帶保護自己的安全。那么如何保證呢?

4.3 信號量的pv操作

信號量操作本質(zhì)上就是計數(shù)器的++或者--,是原子性的。當(dāng)我們預(yù)定資源的時候(--)稱為p操作,釋放資源(++)稱為v操作。
如果信號量的初始值是1就代表了訪問公共資源作為一個整體來使用,一個進程申請了別的進程就不能再申請了,我們把只有兩種狀態(tài)的信號量稱為二元信號量。

4.4 信號量接口

4.4.1 信號量申請semget

#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>int semget(key_t key, int nsems, int semflg);

參數(shù)介紹:

nsems:表示申請信號量的個數(shù)
第一個和第三個參數(shù)就跟前面的shmget相同。
返回值:信號量集創(chuàng)建成功時,semget函數(shù)返回的一個有效的信號量集標(biāo)識符

4.4.2 信號量控制semctl

#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>
int semctl(int semid, int semnum, int cmd, ...);

參數(shù)介紹:
semid:信號量標(biāo)識符
semnum:信號量的下標(biāo),默認(rèn)0

4.4.3 信號量操作semop

#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>
int semop(int semid, struct sembuf *sops, unsigned nsops);

參數(shù)介紹:
sembuf:一個結(jié)構(gòu)體

在這里插入圖片描述
sem_num:信號量下標(biāo)。
sem_op:1表示++p操作,-1表示--v操作。
sem_flg:選項設(shè)為0即可。

nsops:有多少個sembuf結(jié)構(gòu)體。

五、總結(jié)

我們可以發(fā)現(xiàn),共享內(nèi)存、消息隊列、信號量接口相似度非常高,尤其是獲取與刪除,這些都是system V標(biāo)準(zhǔn)的進程間通信。
他們的第一個成員都是ipc_perm

struct ipc_perm {key_t          __key;    /* Key supplied to shmget(2) */uid_t          uid;      /* Effective UID of owner */gid_t          gid;      /* Effective GID of owner */uid_t          cuid;     /* Effective UID of creator */gid_t          cgid;     /* Effective GID of creator */unsigned short mode;     /* Permissions + SHM_DEST andSHM_LOCKED flags */unsigned short __seq;    /* Sequence number */};

我們可能會申請共享內(nèi)存、消息隊列、信號量的任意一種,那么操作系統(tǒng)如何組織它們呢?

因為ipc_perm是一樣的,所以可以維護一個struct ipc_perm*的指針數(shù)組,存共享內(nèi)存、消息隊列、信號量它們的第一個元素的地址,也就是&ipc_perm
而我們知道結(jié)構(gòu)體的第一個成員的地址和結(jié)構(gòu)體對象的地址在數(shù)字上是相等的。

所以當(dāng)我們想使用的時候直接強轉(zhuǎn)成想用的結(jié)構(gòu)體(共享內(nèi)存、消息隊列、信號量)就可以。

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

相關(guān)文章:

  • 能免費做網(wǎng)站嗎信息流廣告模板
  • 成都定制企業(yè)網(wǎng)站制作免費學(xué)生網(wǎng)頁制作成品代碼
  • 專業(yè)手機網(wǎng)站制作公司網(wǎng)站快速排名服務(wù)商
  • 做網(wǎng)站開發(fā)人員架構(gòu)市場營銷
  • win7如何做網(wǎng)站建立自己的網(wǎng)站平臺
  • 鋼管網(wǎng)站模板國外搜索引擎大全不屏蔽
  • 學(xué)做川菜的網(wǎng)站站長工具whois查詢
  • 山西電力建設(shè)三公司網(wǎng)站免費的行情網(wǎng)站app
  • 網(wǎng)站建設(shè) 公司 常見問題seo綜合查詢是什么
  • 湘潭網(wǎng)站建站公司武漢seo結(jié)算
  • 淄博的大型網(wǎng)站建設(shè)怎樣做網(wǎng)站
  • 網(wǎng)站建設(shè)費用能否計入開辦費百度論壇發(fā)帖
  • 新鄉(xiāng)市建設(shè)工程信息網(wǎng)seo工作內(nèi)容有哪些
  • 深圳網(wǎng)站制作工作室百度推廣介紹
  • 工業(yè)設(shè)計相關(guān)網(wǎng)站公司官網(wǎng)搭建
  • 站長網(wǎng)站的優(yōu)勢百度網(wǎng)絡(luò)營銷中心
  • 西安做網(wǎng)站電話百度一下你就知道網(wǎng)頁
  • 佛山新網(wǎng)站制作平臺鄭州seo優(yōu)化公司
  • 門戶網(wǎng)站解決方案蘇州seo建站
  • 臨淄網(wǎng)站建設(shè)公司網(wǎng)站推廣搜索
  • 麗江網(wǎng)站建設(shè)怎么自己創(chuàng)建一個網(wǎng)站
  • ppt做視頻 模板下載網(wǎng)站營銷方式和渠道
  • 重慶網(wǎng)站建設(shè)合肥公司網(wǎng)站怎么宣傳
  • 做界面網(wǎng)站用什么語言seo教程
  • 青海住房與建設(shè)廳網(wǎng)站廣東網(wǎng)約車漲價
  • 用dw做淘客網(wǎng)站的步驟南京百度推廣開戶
  • 工控做網(wǎng)站網(wǎng)站免費軟件
  • 做企業(yè)網(wǎng)站注意些啥百度指數(shù)數(shù)據(jù)分析平臺官網(wǎng)
  • 專門做圖片的網(wǎng)站有哪些今日軍事新聞
  • 網(wǎng)站建設(shè)銷售實習(xí)服務(wù)營銷策劃方案