Linux-System ist ein Betriebssystem, das die gleichzeitige Ausführung mehrerer Aufgaben unterstützt. Es kann mehrere Prozesse gleichzeitig ausführen und dadurch die Systemauslastung und -effizienz verbessern. Wenn jedoch Datenaustausch und Zusammenarbeit zwischen diesen Prozessen erforderlich sind, müssen einige IPC-Methoden (Inter-Process Communication) verwendet werden, z. B. Signale, Nachrichtenwarteschlangen, Semaphoren usw. Unter diesen ist der gemeinsam genutzte Speicher von System V eine relativ fortschrittliche und schnelle IPC-Methode, die es zwei oder mehr Prozessen ermöglicht, Daten über einen Speicherbereich auszutauschen, ohne dass Daten kopiert und konvertiert werden müssen. In diesem Artikel wird die Methode des gemeinsam genutzten Speichers von System V in Linux-Systemen vorgestellt, einschließlich des Erstellens, Zuordnens, Lesens, Schreibens, Aufhebens der Zuordnung und Löschens von gemeinsam genutztem Speicher.
#include #include #include ftok() //获取key值 shmget() //创建/获取共享内存 shmat() //挂接共享内存 shmdt() //脱接共享内存 shmctl() //删除共享内存
//获取key值, key值是System V IPC的标识符,成功返回key,失败返回-1设errno //同pathname+同 proj_id==>同key_t; key_t ftok(const char *pathname, int proj_id);
Pfadname: Dateiname
Projekt_ID: eine Zahl von 1 bis 255, die die Projekt_ID darstellt
key_t key=ftok(".",100); //“.”就是一个存在且可访问的路径, 100是假设的proj_id if(-1==key) perror("ftok"),exit(-1);
//创建/获取共享内存,成功返回共享内存的标识符shmid,失败返回-1设errno int shmget(key_t key, size_t size, int shmflg); //多设为int shmid=... 和shmat()一起用比较好看
key: Der Rückgabewert von ftok()
size: Die Größe des gemeinsam genutzten Speichers wird tatsächlich entsprechend der Seitengröße (PAGE_SIZE) zugewiesen. 0 bedeutet, den zugewiesenen gemeinsam genutzten Speicher zu erhalten
shmflg: spezifisches Operationsflag
//创建shared memory shmid=shmget(key,4,IPC_CREAT|IPC_EXCL|0664); if(-1==shmid) perror("shmget"),exit(-1);
: Was nützt ftok(), da shmget() erstellt werden kann? A
: shmget dient zum Erstellen eines gemeinsamen Speichers, ftok() wird nur zum Generieren eines Schlüssels verwendet An der Stelle des Schlüssels kann auch eine Nummer ausgeführt werden, aber im Vergleich zu der vom System generierten Nummer kann es leicht zu Konflikten kommen. Daher ist es am besten, ftok zum Generieren eines Schlüssels zu verwenden
shmat()
//挂接共享内存,成功返回映射内存的地址,失败返回(void*)-1设errno void *shmat(int shmid, const void *shmaddr, int shmflg);
shmaddr
NULL bedeutet vom System ausgewählt (wie mmap())
//挂接共享内存 void* pv=shmat(shmid,NULL,0); if((void*)-1==pv) perror("shmat"),exit(-1);
//脱接共享内存,成功返回0,失败返回-1设errno int shmdt(const void *shmaddr); //脱接shm int res=shmdt(pv); if(-1==res) perror("shmdt"),exit(-1);
//共享内存管理,成功返回0,失败返回-1设errno int shmctl(int shmid, int cmd, struct shmid_ds *buf);
buf: ein Zeiger vom Typ shmid_ds
struct shmid_ds { struct ipc_perm shm_perm; /* Ownership and permissions */ size_t shm_segsz; /* Size of segment (bytes) */ time_t shm_atime; /* Last attach time */ time_t shm_dtime; /* Last detach time */ time_t shm_ctime; /* Last change time */ pid_t shm_cpid; /* PID of creator */ pid_t shm_lpid; /* PID of last shmat(2)/shmdt(2) */ shmatt_t shm_nattch; /* No. of current attaches */ ... }; // 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 and SHM_LOCKED flags */ unsigned short __seq; /* Sequence number */ };
IPC_STAT表示从内核中拷贝关于这个shmid的信息到buf指向的shmid_ds中
IPC_SET 将buf指向的shmid_ds的信息写入到内核的结构体中,同时更新成员shm_ctime
IPC_RMID销毁共享内存
IPC_INFO(Linux-specific)返回系统对共享内存的限制写入到buf指向的时shminfo结构体中
//_GNU_SOURCE struct shminfo { unsigned long shmmax; /* Maximum segment size */ unsigned long shmmin; /* Minimum segment size; always 1 */ unsigned long shmmni; /* Maximum number of segments */ unsigned long shmseg; /* Maximum number of segments that a process can attach; unused within kernel */ unsigned long shmall; /* Maximum number of pages of shared memory, system-wide */ }; //shmmni, shmmax, and shmall 可以童工/proc里的同名文件进行修改
SHM_INFO(Linux-specific) 返回一个shm_info结构体来表示该共享内存消耗的系统资源
//_GNU_SOURCE struct shm_info { int used_ids; /* # of currently existing segments */ unsigned long shm_tot; /* Total number of shared memory pages */ unsigned long shm_rss; /* # of resident shared memory pages */ unsigned long shm_swp; /* # of swapped shared memory pages */ unsigned long swap_attempts; /* Unused since Linux 2.4 */ unsigned long swap_successes;/* Unused since Linux 2.4 */ };
SHM_STAT(Linux-specific) 为IPC_STAT返回一个shmid_ds结构结构体,不同的是shmid的参数不是一个标识符,而是内核中一个包含了系统中所有共享内存信息的索引
SHM_LOCK防止系统将共享内存放到swap区,IPC_STAT读到的信息中SHM_LOCKED标记就被设置了
SHM_UNLOCK 解除锁定,即允许共享内存被系统放到swap区
//使用IPC_RMID删除共享内存 int res=shmctl(shmid,IPC_RMID,NULL); if(-1==res) perror("shmctl"),exit(-1);
//Sys V IPC shm int shmid; //定义全局变量记录id void fa(int signo){ printf("deleting shared memories...\n"); sleep(3);//其实没用 int res=shmctl(shmid,IPC_RMID,NULL); if(-1==res) perror("shmctl"),exit(-1); printf("delete success\n"); exit(0); //ctrl+C已经不能结束while(1),用exit(0)来终结 } int main(){ //获取key key_t key=ftok(".",100); //.就是一个存在且可访问的路径, 100是随便给的 if(-1==key) perror("ftok"),exit(-1); printf("key=%#x\n",key); //打印出进制的标示,即0x //创建shared memory shmid=shmget(key,4,IPC_CREAT|IPC_EXCL|0664); if(-1==shmid) perror("shmget"),exit(-1); printf("shmid=%d\n",shmid); //挂接shm void* pv=shmat(shmid,NULL,0); if((void*)-1==pv) perror("shmat"),exit(-1); printf("link shared memory success\n"); //访问shm int* pi=(int*)pv; *pi=100; //脱接shm int res=shmdt(pv); if(-1==res) perror("shmdt"),exit(-1); printf("unlink success\n"); //如果不再使用,删除shm printf("删除共享内存请按Ctrl C...\n"); if(SIG_ERR==signal(SIGINT,fa)) perror("signal"),exit(-1); while(1); return 0; }
本文介绍了Linux系统中System V 共享内存的方法,包括共享内存的创建、映射、读写、解除映射和删除等方面。通过了解和掌握这些知识,我们可以更好地使用System V 共享内存来实现进程间通信,提高系统的性能和可靠性。当然,Linux系统中System V 共享内存还有很多其他的特性和用法,需要我们不断地学习和探索。希望本文能给你带来一些启发和帮助。
Das obige ist der detaillierte Inhalt vonLinux IPC System V Shared Memory: Ein fortschrittlicher Ansatz für den Hochgeschwindigkeits-Datenaustausch. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!