怎么做可以把下圖中相同的的款號數量一鍵整理成一個款號然后款號后面就是這個款的總數
860
2025-04-01
1 共享內存的概念
共享內存是指多個進程可以把一段內存共同的內存映射到自己的進程空間中,從而實現數據的共享和傳輸,它是存在與內核級別的一種資源,是所有進程間通信中方式最快的一種。
在shell環境下可以使用ipcs查看當前系統IPC中的狀態,例如當前的電腦中:
$ ipcs ------ Message Queues -------- key msqid owner perms used-bytes messages ------ Shared Memory Segments -------- key shmid owner perms bytes nattch status 0x00000000 2260992 deeplearni 600 524288 2 dest 0x00000000 2490369 deeplearni 600 67108864 2 dest 0x00000000 163842 root 777 7680 2 0x00000000 196611 root 777 8294400 2 0x00000000 229380 root 777 4096 2 0x00000000 262149 root 777 8192 2 0x00000000 294918 root 777 12288 2 ...省略 0x00000000 2064444 root 777 233472 2 0x00000000 2097213 root 777 237568 2 0x00000000 2129982 root 777 241664 2 0x00000000 2162751 root 777 245760 2 0x00000000 2654272 deeplearni 600 524288 2 dest 0x00000000 2687041 deeplearni 600 524288 2 dest 0x00000000 2719810 deeplearni 600 524288 2 dest 0x00000000 2752579 deeplearni 600 524288 2 dest 0x00000000 2981956 deeplearni 600 524288 2 dest 0x00000000 2949189 deeplearni 600 524288 2 dest 0x00000000 3014726 deeplearni 600 67108864 2 dest ------ Semaphore Arrays -------- key semid owner perms nsems
該命令使用附加參數可單獨查看某一IPC:-m(共享內存),-q(消息隊列),-s(信號量)。
由于多個進程對同一塊內存區域具有訪問權限,各進程間的同步問題需要解決,可以配合信號量進行控制。
對于每一個共享內存段,內核會為其維護一個shmid_ds類型的結構體:
// 摘自所用ubuntu18.04電腦中的/usr/include/i386-linux-gnu/bits/shm.h struct shmid_ds { struct ipc_perm shm_perm; /* operation permission struct */ size_t shm_segsz; /* size of segment in bytes */ __time_t shm_atime; /* time of last shmat() */ #ifndef __x86_64__ unsigned long int __glibc_reserved1; #endif __time_t shm_dtime; /* time of last shmdt() */ #ifndef __x86_64__ unsigned long int __glibc_reserved2; #endif __time_t shm_ctime; /* time of last change by shmctl() */ #ifndef __x86_64__ unsigned long int __glibc_reserved3; #endif __pid_t shm_cpid; /* pid of creator */ __pid_t shm_lpid; /* pid of last shmop */ shmatt_t shm_nattch; /* number of current attaches */ __syscall_ulong_t __glibc_reserved4; __syscall_ulong_t __glibc_reserved5; };
2 共享內存的相關操作
2.1 創建/打開共享內存
創建共享內存需要用到shmget()函數,原型如下:
#include
創建成功返回共享內存的ID,出錯返回-1。
參數key為共享內存的鍵值,參數size為創建共享內存的大小,參數flag為調用函數的操作類型。參數key和參數flag共同決定的shmget()的作用:
key為IPC_PRIVATE時,創建一個新的共享內存,flag取值無效。
key不為IPC_PRIVATE,且flag設置了IPC_CREAT位,而沒有設置IPC_EXCL位時,如果key為內核中的已存在的共享內存鍵值,則打開,否則創建一個新的共享內存。
key不為IPC_PRIVATE,且flag設置了IPC_CREAT和IPC_EXCL位時,則只執行創建共享內存操作。如果key為內核中的已存在的共享內存鍵值,返回EEXIST錯誤。
2.2 共享內存的附加(映射)
創建一個共享內存后,某個進程若想使用,需要將此內存區域附加(attach)到自己的進程空間(或稱地址映射),需要用到shmat()函數:
#include
運行成功返回指向共享內存段的地址指針,出錯返回-1。
參數shmid為共享內存的ID,參數addr和參數flag共同說明要引入的地址值,通常只有2種用法:
addr為0,表明讓內核來決定第1個可引用的位置
addr非0,且flag中指定SHM_RND,則此段引入到addr所指向的位置。
shmat()函數執行成功后,會將shmid的共享內存段的shmid_ds結構的shm_nattch計數器值加1。
2.3 共享內存的分離
當進程使用完共享內存后,需要將共享內存從其進程空間中去除(detach),使用shmdt()函數:
#include
運行成功返回0,出錯返回-1。
參數addr是調用shmat()函數的返回值,即共享內存段的地址指針。shmdt()函數執行成功后,shm_nattch計數器值減1。
2.4 共享內存的控制
使用shmctl()可以對共享內存段進行多種控制操作,函數原型:
#include
運行成功返回0,出錯返回-1。
參數shmid為共享內存的ID,參數cmd指明了所要進行的操作,與參數*buf配合使用:
3 編程示例
基本步驟:
生成key,ftok()
使用key創建/獲得一個共享內存,shmget()
映射共享內存,得到虛擬地址,shmat()
使用共享內存,通過地址指針
移除映射,shmdt()
銷毀共享內存,shmctl()
3.1 示例1
進程1創建共享內存并寫入數據,shm1.c:
#include
進程2讀取共享內存中的內容,shm2.c;
#include
編譯運行測試,在一個shell中先運行shm1程序:
$ ./shm1 key=0xc81102ed shmid=0x2e8047 use Enter to destroy the share memory
在另一個shell中先運行shm2程序:
$ ./shm2 key=0xc81102ed shmid=0x2e8047 x=0xaaaaaaaa y=0x55555555
可以看到通信成功,在第一個shell中按下“Enter”可以銷毀共享內存。
3.2 示例2
示例1使用ftok()函數生成的key創建共享內存,本示例使用IPC_PRIVATE參數創建共享內存。
創建一個共享內存,并輸出其ID號,create_shm.c:
#include
打開指定ID的共享內存,寫入內容,write_shm.c:
#include
打開指定ID的共享內存,讀取內容,read_shm.c:
#include
編譯上述3個程序,首先運行create_shm程序創建一個共享內存:
$ ./create_shm create a shared memory segment successfully: 3080264 ------ Shared Memory Segments -------- key shmid owner perms bytes nattch status 0x00000000 2260992 deeplearni 600 524288 2 dest 0x00000000 2490369 deeplearni 600 67108864 2 dest 0x00000000 163842 root 777 7680 2 0x00000000 196611 root 777 8294400 2 0x00000000 229380 root 777 4096 2 ...省略 0x00000000 2031675 root 777 229376 2 0x00000000 2064444 root 777 233472 2 0x00000000 2097213 root 777 237568 2 0x00000000 2129982 root 777 241664 2 0x00000000 2162751 root 777 245760 2 0x00000000 2654272 deeplearni 600 524288 2 dest 0x00000000 2687041 deeplearni 600 524288 2 dest 0x00000000 2719810 deeplearni 600 524288 2 dest 0x00000000 2752579 deeplearni 600 524288 2 dest 0x00000000 2981956 deeplearni 600 524288 2 dest 0x00000000 2949189 deeplearni 600 524288 2 dest 0x00000000 3014726 deeplearni 600 67108864 2 dest 0xc81102ed 3047495 deeplearni 666 8 0 0x00000000 3080264 deeplearni 666 4096 0
可以看到程序創建了一個shmid為3080264的共享內存,然后可以運行write_shm程序,需要將ID號作為參數:
$ ./write_shm 3080264
雖然沒有輸出,但程序已將內容寫入共享內存,并且共享內存沒有被刪除,可以運行read_shm程序讀取共享內存中的內容:
$ ./read_shm 3080264 name:b age 20 name:c age 21 name:d age 22 name:e age 23 name:f age 24 name:g age 25 name:h age 26 name:i age 27 name:j age 28 name:k age 29
可以看到,程序讀取到了共享內存中存儲的10個字符。
另外,無用的共享內存也可以通過命令的方式收到刪除,使用ipcrm -m 共享內存id的形式,如:
$ ipcrm -m 3080264
此時再用ipcs -m命令查看,已經沒有shmid為3080264的共享內存。
Linux 任務調度
版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。
版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。