>  기사  >  시스템 튜토리얼  >  Linux IPC System V 공유 메모리: 고속 데이터 교환에 대한 고급 접근 방식

Linux IPC System V 공유 메모리: 고속 데이터 교환에 대한 고급 접근 방식

WBOY
WBOY앞으로
2024-02-13 08:30:321212검색

Linux 시스템은 다중 작업의 동시 실행을 지원하는 운영 체제로, 동시에 여러 프로세스를 실행할 수 있어 시스템 활용도와 효율성이 향상됩니다. 그러나 이러한 프로세스 간에 데이터 교환 및 협업이 필요한 경우 신호, 메시지 큐, 세마포어 등과 같은 일부 프로세스 간 통신(IPC) 방법을 사용해야 합니다. 그 중 시스템 V 공유 메모리는 2개 이상의 프로세스가 데이터 복사 및 변환 없이 메모리 영역을 통해 데이터를 교환할 수 있도록 하는 비교적 진보된 고속 IPC 방식이다. 이 기사에서는 공유 메모리의 생성, 매핑, 읽기, 쓰기, 매핑 해제 및 삭제를 포함하여 Linux 시스템에서 System V 공유 메모리의 방법을 소개합니다.

Linux IPC System V 共享内存:一种实现高速数据交换的高级方式

모델

으아아아

ftok()

으아아아

pathname: 파일 이름
proj_id: 1에서 255 사이의 숫자, project_id를 나타냄

으아아아

shmget()

으아아아

key: ftok()의 반환 값
size: 공유 메모리의 크기는 실제로 페이지 크기(PAGE_SIZE)에 따라 할당됩니다. 0은 할당된 공유 메모리
shmflg를 얻는 것을 의미합니다. 특정 작업 플래그

  • IPC_CREAT: 없으면 만듭니다. shmflg에 "|권한 정보"가 필요합니다. 예: |0664, 있으면 엽니다.
  • IPC_EXCL: IPC_CREAT와 함께 사용되며, 존재하는 경우 생성이 실패합니다. ==> 오류, errno
  • 설정
  • 0: 기존 공유 메모리 가져오기
아아아아

Q: shmget()은 생성할 수 있으므로 ftok()의 용도는 무엇입니까?
A: shmget은 공유 메모리를 생성하는 것이고, ftok()는 키를 생성하는 데만 사용됩니다. 키가 있는 위치에 마음대로 숫자를 실행할 수도 있지만 시스템에서 생성한 것에 비해 충돌이 발생하기 쉽기 때문에 키를 생성하려면 ftok를 사용하는 것이 가장 좋습니다

shmat()

으아아아

shmid: shmget()
shmaddr

의 반환 값
  • NULL은 시스템에 의해 선택되었음을 의미합니다(mmap()과 동일)
  • NULL이 아니고 shflg가 SHM_RND인 경우 페이지 정렬 원칙에 따라 shmaddr에서 시작하여 가장 가까운 주소부터 포인트가 할당됩니다. 그렇지 않으면 shmaddr에 지정된 주소가 페이지 정렬되어야 합니다
  • shmflg: 작업 플래그입니다. 0을 지정하세요.
    • SHM_RDONLY는 공유 메모리에 연결된 프로세스에 읽기 권한이 있어야 함을 의미합니다
    • SHM_REMAP(Linux에만 해당)은 매핑할 공유 메모리에 이미 기존 메모리가 있는 경우 이전 메모리를 교체한다는 의미입니다
아아아아

shmdt()

으아아아

shmctl()

으아아아

shmid: shmget()에 의해 반환된 공유 메모리의 ID
buf: shmid_ds

유형의 포인터 으아아아

cmd

  • 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 共享内存还有很多其他的特性和用法,需要我们不断地学习和探索。希望本文能给你带来一些启发和帮助。

위 내용은 Linux IPC System V 공유 메모리: 고속 데이터 교환에 대한 고급 접근 방식의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
이 기사는 lxlinux.net에서 복제됩니다. 침해가 있는 경우 admin@php.cn으로 문의하시기 바랍니다. 삭제