91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

linux進程通信共享內存原理是什么

發布時間:2021-07-15 18:26:09 來源:億速云 閱讀:235 作者:chen 欄目:大數據

本篇內容主要講解“linux進程通信共享內存原理是什么”,感興趣的朋友不妨來看看。本文介紹的方法操作簡單快捷,實用性強。下面就讓小編來帶大家學習“linux進程通信共享內存原理是什么”吧!

1 有一個全局的結構體數據,每次需要一塊共享的內存時(shmget),從里面取一個結構體,記錄相關的信息。

   
     
 
    
    

struct shmid_ds {
       // 權限相關
struct ipc_perm shm_perm; /* operation perms */
// 共享內存的大小
int 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 */
// 創建該結構體的進程
unsigned short shm_cpid; /* pid of creator */
unsigned short shm_lpid; /* pid of last operator */
// 當前使用該共享內存的進程數
short shm_nattch; /* no. of current attaches */
/* the following are private */
// 共享內存的頁數
unsigned short   shm_npages; /* size of segment (pages) */
// 指向共享的物理內存的指針
unsigned long   *shm_pages; /* array of ptrs to frames -> SHMMAX */
// 使用該共享內存的進程信息
struct vm_area_struct *attaches; /* descriptors for attaches */
}              

2 調用shmat的時候傳入shmget返回的id。shmat根據id找到對應的shmid_ds 結構體。新建一個vm_area_struct結構體。開始地址和結束地址根據shmid_ds 中的信息計算,也就是用戶申請的大小。接著把vm_area_struct插入進程中管理vm_area_struct的avl樹。并且把一些上下文信息保存到頁表項。缺頁中斷的時候在shm_swap_in里使用。

   
     
 
    
    

       shm_sgn = shmd->vm_pte + ((shmd->vm_offset >> PAGE_SHIFT) << SHM_IDX_SHIFT);
for (tmp = shmd->vm_start; tmp < shmd->vm_end; tmp += PAGE_SIZE,
shm_sgn += (1 << SHM_IDX_SHIFT)) {
page_dir = pgd_offset(shmd->vm_task,tmp);
page_middle = pmd_alloc(page_dir,tmp);
if (!page_middle)
return -ENOMEM;
page_table = pte_alloc(page_middle,tmp);
if (!page_table)
return -ENOMEM;
pte_val(*page_table) = shm_sgn;
}              

3 進程訪問共享內存范圍中的地址時,觸發缺頁中斷。

   
     
 
    
    

void do_no_page(struct vm_area_struct * vma, unsigned long address,
int write_access)
{
pte_t * page_table;
pte_t entry;
unsigned long page;
// 在進程頁表里獲取address對應的頁表項地址
page_table = get_empty_pgtable(vma->vm_task,address);
// 分配失敗則返回
if (!page_table)
return;
entry = *page_table;
// 已經建立了虛擬地址到物理地址的映射,返回
if (pte_present(entry))
return;
// 還沒有建立映射
if (!pte_none(entry)) {
do_swap_page(vma, address, page_table, entry, write_access);
return;
}
       ......
}              

在缺頁中斷中調用do_swap_page。

   
     
 
    
    

static inline void do_swap_page(struct vm_area_struct * vma, unsigned long address,
pte_t * page_table, pte_t entry, int write_access)
{
pte_t page;

if (!vma->vm_ops || !vma->vm_ops->swapin) {
swap_in(vma, page_table, pte_val(entry), write_access);
return;
}
page = vma->vm_ops->swapin(vma, address - vma->vm_start + vma->vm_offset, pte_val(entry));
if (pte_val(*page_table) != pte_val(entry)) {
free_page(pte_page(page));
return;
}
if (mem_map[MAP_NR(pte_page(page))] > 1 && !(vma->vm_flags & VM_SHARED))
page = pte_wrprotect(page);
++vma->vm_task->mm->rss;
++vma->vm_task->mm->maj_flt;
       // 寫入物理地址
*page_table = page;
return;
}              

其中vma->vm_ops->swapin對應shm.c的shm_swap_in

   
     
 
    
    

       pte_val(pte) = shp->shm_pages[idx];
// 還沒有分配物理內存
if (!pte_present(pte)) {
// 分配物理內存
unsigned long page = get_free_page(GFP_KERNEL);
               ...
               // 記錄物理地址
               shp->shm_pages[idx] = pte_val(pte);
       }
       mem_map[MAP_NR(pte_page(pte))]++;
return pte_modify(pte, shmd->vm_page_prot);              

如果還沒分配物理地址則分配,否則直接范圍已經分配的地址。do_swap_page函數的最后一句會把物理地址寫入進程的頁表項。下次就不會缺頁中斷了。

  同理,其他進程共享該塊內存的時候,如果訪問范圍內的地址,處理過程是類似的。進程訪問某一個地址,發生缺頁中斷,然后進入do_swap_page函數處理,再到shm_swap_in。發現這時候共享內存已經映射了物理地址。最后改寫自己的頁表項。因為各個進程都對應同一塊內存,所以操作的時候會互相感知,實現通信。

linux進程通信共享內存原理是什么

到此,相信大家對“linux進程通信共享內存原理是什么”有了更深的了解,不妨來實際操作一番吧!這里是億速云網站,更多相關內容可以進入相關頻道進行查詢,關注我們,繼續學習!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

武冈市| 湘阴县| 胶南市| 芜湖市| 阜南县| 丰原市| 临邑县| 阳原县| 铜川市| 宁化县| 潞西市| 林州市| 伊宁市| 阿巴嘎旗| 黄骅市| 湟源县| 聂荣县| 搜索| 永丰县| 郑州市| 渝北区| 石渠县| 灵台县| 镇康县| 梅河口市| 公安县| 万宁市| 仁化县| 菏泽市| 临汾市| 宁国市| 张家川| 临朐县| 弋阳县| 阜城县| 陇南市| 辰溪县| 清河县| 水富县| 津南区| 南通市|