最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

C語言中共享內(nèi)存完整示例示例

 更新時間:2025年11月17日 09:49:26   作者:山,離天三尺三  
本文主要介紹了C語言中共享內(nèi)存完整示例示例,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧

完整的共享內(nèi)存通信示例

頭文件 (shm_common.h)

#ifndef __SHM_COMMON_H__
#define __SHM_COMMON_H__

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <sys/types.h>
#include <errno.h>

#define SHM_KEY 0x1234          // 共享內(nèi)存鍵值
#define SHM_SIZE 1024           // 共享內(nèi)存大小
#define MAX_DATA_SIZE 512       // 最大數(shù)據(jù)長度

// 共享內(nèi)存數(shù)據(jù)結(jié)構(gòu)
struct shm_data {
    int written;                // 數(shù)據(jù)寫入標(biāo)志: 0-未寫入, 1-已寫入
    char data[MAX_DATA_SIZE];   // 數(shù)據(jù)緩沖區(qū)
};

// 函數(shù)聲明
int create_shared_memory(key_t key, size_t size, int flags);
void* attach_shared_memory(int shmid);
int detach_shared_memory(const void *shm_addr);
int destroy_shared_memory(int shmid);
void print_shared_memory_info(int shmid);

#endif

寫入進程 (writer.c)

#include "shm_common.h"

int main() {
    printf("=== 共享內(nèi)存寫入進程 ===\n");
    
    // 1. 創(chuàng)建共享內(nèi)存
    int shmid = create_shared_memory(SHM_KEY, SHM_SIZE, IPC_CREAT | 0666);
    if (shmid == -1) {
        perror("創(chuàng)建共享內(nèi)存失敗");
        exit(EXIT_FAILURE);
    }
    printf("創(chuàng)建共享內(nèi)存成功, shmid = %d\n", shmid);
    
    // 2. 顯示共享內(nèi)存信息
    print_shared_memory_info(shmid);
    
    // 3. 附加共享內(nèi)存到進程
    struct shm_data *shared_data = (struct shm_data*)attach_shared_memory(shmid);
    if (shared_data == (void*)-1) {
        perror("附加共享內(nèi)存失敗");
        destroy_shared_memory(shmid);
        exit(EXIT_FAILURE);
    }
    printf("附加共享內(nèi)存成功\n");
    
    // 4. 向共享內(nèi)存寫入數(shù)據(jù)
    printf("開始向共享內(nèi)存寫入數(shù)據(jù)...\n");
    
    // 初始化共享內(nèi)存區(qū)域
    memset(shared_data, 0, sizeof(struct shm_data));
    
    for (int i = 1; i <= 5; i++) {
        // 準(zhǔn)備數(shù)據(jù)
        snprintf(shared_data->data, MAX_DATA_SIZE, 
                "這是第 %d 條消息 - 時間戳: %ld", i, time(NULL));
        
        // 標(biāo)記數(shù)據(jù)已寫入
        shared_data->written = 1;
        printf("寫入數(shù)據(jù): %s\n", shared_data->data);
        
        // 等待讀取進程讀取
        printf("等待讀取進程讀取數(shù)據(jù)...\n");
        sleep(2);
        
        // 等待數(shù)據(jù)被讀取
        while (shared_data->written == 1) {
            usleep(100000); // 等待100ms
        }
        printf("數(shù)據(jù)已被讀取,準(zhǔn)備寫入下一條...\n\n");
    }
    
    // 5. 寫入結(jié)束標(biāo)志
    strcpy(shared_data->data, "END");
    shared_data->written = 1;
    printf("寫入結(jié)束標(biāo)志\n");
    
    // 6. 清理資源
    sleep(1); // 確保讀取進程收到結(jié)束標(biāo)志
    detach_shared_memory(shared_data);
    destroy_shared_memory(shmid);
    
    printf("寫入進程結(jié)束\n");
    return 0;
}

讀取進程 (reader.c)

#include "shm_common.h"

int main() {
    printf("=== 共享內(nèi)存讀取進程 ===\n");
    
    // 1. 獲取已存在的共享內(nèi)存
    int shmid = create_shared_memory(SHM_KEY, SHM_SIZE, 0666);
    if (shmid == -1) {
        perror("獲取共享內(nèi)存失敗");
        exit(EXIT_FAILURE);
    }
    printf("獲取共享內(nèi)存成功, shmid = %d\n", shmid);
    
    // 2. 顯示共享內(nèi)存信息
    print_shared_memory_info(shmid);
    
    // 3. 附加共享內(nèi)存到進程
    struct shm_data *shared_data = (struct shm_data*)attach_shared_memory(shmid);
    if (shared_data == (void*)-1) {
        perror("附加共享內(nèi)存失敗");
        exit(EXIT_FAILURE);
    }
    printf("附加共享內(nèi)存成功\n");
    
    // 4. 從共享內(nèi)存讀取數(shù)據(jù)
    printf("開始從共享內(nèi)存讀取數(shù)據(jù)...\n\n");
    
    while (1) {
        // 等待新數(shù)據(jù)
        if (shared_data->written == 1) {
            printf("讀取到數(shù)據(jù): %s\n", shared_data->data);
            
            // 檢查結(jié)束標(biāo)志
            if (strcmp(shared_data->data, "END") == 0) {
                printf("收到結(jié)束標(biāo)志,停止讀取\n");
                break;
            }
            
            // 標(biāo)記數(shù)據(jù)已讀取
            shared_data->written = 0;
            printf("數(shù)據(jù)已處理,等待下一條數(shù)據(jù)...\n\n");
        } else {
            usleep(500000); // 等待500ms再檢查
        }
    }
    
    // 5. 清理資源
    detach_shared_memory(shared_data);
    printf("讀取進程結(jié)束\n");
    
    return 0;
}

工具函數(shù)實現(xiàn) (shm_common.c)

#include "shm_common.h"

/**
 * 創(chuàng)建或獲取共享內(nèi)存段
 * @param key: 共享內(nèi)存鍵值
 * @param size: 共享內(nèi)存大小
 * @param flags: 創(chuàng)建標(biāo)志和權(quán)限
 * @return: 成功返回共享內(nèi)存ID,失敗返回-1
 */
int create_shared_memory(key_t key, size_t size, int flags) {
    int shmid = shmget(key, size, flags);
    if (shmid == -1) {
        perror("shmget failed");
    }
    return shmid;
}

/**
 * 將共享內(nèi)存附加到進程地址空間
 * @param shmid: 共享內(nèi)存ID
 * @return: 成功返回共享內(nèi)存地址,失敗返回(void*)-1
 */
void* attach_shared_memory(int shmid) {
    void *shm_addr = shmat(shmid, NULL, 0);
    if (shm_addr == (void*)-1) {
        perror("shmat failed");
    }
    return shm_addr;
}

/**
 * 從進程分離共享內(nèi)存
 * @param shm_addr: 共享內(nèi)存地址
 * @return: 成功返回0,失敗返回-1
 */
int detach_shared_memory(const void *shm_addr) {
    int result = shmdt(shm_addr);
    if (result == -1) {
        perror("shmdt failed");
    } else {
        printf("共享內(nèi)存分離成功\n");
    }
    return result;
}

/**
 * 銷毀共享內(nèi)存段
 * @param shmid: 共享內(nèi)存ID
 * @return: 成功返回0,失敗返回-1
 */
int destroy_shared_memory(int shmid) {
    int result = shmctl(shmid, IPC_RMID, NULL);
    if (result == -1) {
        perror("shmctl IPC_RMID failed");
    } else {
        printf("共享內(nèi)存銷毀成功\n");
    }
    return result;
}

/**
 * 顯示共享內(nèi)存信息
 * @param shmid: 共享內(nèi)存ID
 */
void print_shared_memory_info(int shmid) {
    struct shmid_ds shm_info;
    
    if (shmctl(shmid, IPC_STAT, &shm_info) == -1) {
        perror("shmctl IPC_STAT failed");
        return;
    }
    
    printf("=== 共享內(nèi)存信息 ===\n");
    printf("共享內(nèi)存ID: %d\n", shmid);
    printf("鍵值: 0x%x\n", shm_info.shm_perm.__key);
    printf("大小: %lu 字節(jié)\n", shm_info.shm_segsz);
    printf("創(chuàng)建者PID: %d\n", shm_info.shm_cpid);
    printf("最后操作PID: %d\n", shm_info.shm_lpid);
    printf("附加進程數(shù): %lu\n", shm_info.shm_nattch);
    printf("最后附加時間: %ld\n", shm_info.shm_atime);
    printf("最后分離時間: %ld\n", shm_info.shm_dtime);
    printf("最后修改時間: %ld\n", shm_info.shm_ctime);
    printf("==================\n\n");
}

共享內(nèi)存函數(shù)詳細說明

1.shmget()- 創(chuàng)建/獲取共享內(nèi)存

int shmget(key_t key, size_t size, int shmflg);

參數(shù)說明:

  • key_t key: 共享內(nèi)存鍵值
    • IPC_PRIVATE: 創(chuàng)建私有共享內(nèi)存
    • ftok()生成: 使用文件路徑和項目ID生成
  • 自定義整數(shù)值: 如0x1234
  • size_t size: 共享內(nèi)存大?。ㄗ止?jié))
  • int shmflg: 標(biāo)志和權(quán)限的組合
    • IPC_CREAT: 如果不存在則創(chuàng)建
    • IPC_EXCL: 與IPC_CREAT一起使用,如果已存在則失敗
    • 權(quán)限標(biāo)志: 06660600等(八進制)

返回值:

  • 成功: 共享內(nèi)存標(biāo)識符
  • 失敗: -1,并設(shè)置errno

示例:

// 創(chuàng)建新的共享內(nèi)存
int shmid = shmget(0x1234, 1024, IPC_CREAT | 0666);

// 獲取已存在的共享內(nèi)存
int shmid = shmget(0x1234, 0, 0666);

// 創(chuàng)建私有共享內(nèi)存
int shmid = shmget(IPC_PRIVATE, 1024, 0666);

2.shmat()- 附加共享內(nèi)存

void *shmat(int shmid, const void *shmaddr, int shmflg);

參數(shù)說明:

  • int shmid: 共享內(nèi)存ID(shmget返回值)
  • const void *shmaddr: 指定附加地址
    • NULL: 系統(tǒng)自動選擇地址(推薦)
    • 具體地址: 指定附加到哪個地址
  • int shmflg: 附加標(biāo)志
    • SHM_RDONLY: 只讀方式附加
    • 0: 讀寫方式附加

返回值:

  • 成功: 共享內(nèi)存附加地址
  • 失敗: (void*)-1,并設(shè)置errno

示例:

// 讀寫方式附加
char *shm_addr = shmat(shmid, NULL, 0);

// 只讀方式附加
char *shm_addr = shmat(shmid, NULL, SHM_RDONLY);

3.shmdt()- 分離共享內(nèi)存

int shmdt(const void *shmaddr);

參數(shù)說明:

  • const void *shmaddr: 共享內(nèi)存地址(shmat返回值)

返回值:

  • 成功: 0
  • 失敗: -1,并設(shè)置errno

示例:

shmdt(shm_addr);

4.shmctl()- 控制共享內(nèi)存

int shmctl(int shmid, int cmd, struct shmid_ds *buf);

參數(shù)說明:

  • int shmid: 共享內(nèi)存ID
  • int cmd: 控制命令
    • IPC_STAT: 獲取狀態(tài)信息到buf
    • IPC_SET: 設(shè)置共享內(nèi)存參數(shù)
    • IPC_RMID: 標(biāo)記刪除共享內(nèi)存
    • SHM_LOCK: 鎖定共享內(nèi)存(防止交換)
    • SHM_UNLOCK: 解鎖共享內(nèi)存
  • struct shmid_ds *buf: 狀態(tài)信息緩沖區(qū)

返回值:

  • 成功: 0
  • 失敗: -1,并設(shè)置errno

示例:

// 刪除共享內(nèi)存
shmctl(shmid, IPC_RMID, NULL);

// 獲取共享內(nèi)存信息
struct shmid_ds shm_info;
shmctl(shmid, IPC_STAT, &shm_info);

5.ftok()- 生成IPC鍵值

key_t ftok(const char *pathname, int proj_id);

參數(shù)說明:

  • const char *pathname: 存在的文件路徑
  • int proj_id: 項目標(biāo)識符(0-255)

返回值:

  • 成功: IPC鍵值
  • 失敗: -1,并設(shè)置errno

示例:

key_t key = ftok("/tmp/myapp", 'A');

編譯和運行

編譯命令:

# 編譯所有文件
gcc -o writer writer.c shm_common.c
gcc -o reader reader.c shm_common.c

運行步驟:

  1. 先運行寫入進程

./writer
  1. 再運行讀取進程(新終端):

./reader

運行結(jié)果示例:

=== 共享內(nèi)存寫入進程 ===
創(chuàng)建共享內(nèi)存成功, shmid = 98304
=== 共享內(nèi)存信息 ===
共享內(nèi)存ID: 98304
鍵值: 0x1234
大小: 1024 字節(jié)
創(chuàng)建者PID: 1234
最后操作PID: 0
附加進程數(shù): 0
...
寫入數(shù)據(jù): 這是第 1 條消息 - 時間戳: 1634567890
等待讀取進程讀取數(shù)據(jù)...

注意事項

  • 同步問題:共享內(nèi)存需要額外的同步機制(信號量、互斥鎖等)
  • 資源清理:確保進程退出前分離共享內(nèi)存
  • 權(quán)限設(shè)置:根據(jù)安全需求設(shè)置適當(dāng)?shù)臋?quán)限
  • 錯誤處理:檢查所有系統(tǒng)調(diào)用的返回值
  • 內(nèi)存對齊:考慮數(shù)據(jù)結(jié)構(gòu)的內(nèi)存對齊問題

到此這篇關(guān)于C語言中共享內(nèi)存完整示例示例的文章就介紹到這了,更多相關(guān)C語言 共享內(nèi)存內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 深入分析C++中執(zhí)行多個exe文件方法的批處理代碼介紹

    深入分析C++中執(zhí)行多個exe文件方法的批處理代碼介紹

    本篇文章是對C++中執(zhí)行多個exe文件方法的批處理代碼進行了詳細的分析介紹,需要的朋友參考下
    2013-05-05
  • QT結(jié)合百度Ai實現(xiàn)車牌識別

    QT結(jié)合百度Ai實現(xiàn)車牌識別

    當(dāng)下的人工智能勢頭很盛,本文主要介紹了QT結(jié)合百度Ai實現(xiàn)車牌識別,文中通過示例代碼介紹的非常詳細,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2024-03-03
  • C++深入講解new與deleted關(guān)鍵字的使用

    C++深入講解new與deleted關(guān)鍵字的使用

    這篇文章主要介紹了C++中new與deleted關(guān)鍵字的使用,new在動態(tài)內(nèi)存中為對象分配空間并返回一個指向該對象的指針;delete接受一個動態(tài)對象的指針, 銷毀該對象, 并釋放與之關(guān)聯(lián)的內(nèi)存
    2022-05-05
  • 基于Sizeof與Strlen的區(qū)別以及聯(lián)系的使用詳解

    基于Sizeof與Strlen的區(qū)別以及聯(lián)系的使用詳解

    本篇文章是對Sizeof與Strlen的區(qū)別以及聯(lián)系的使用進行了詳細的介紹。需要的朋友參考下
    2013-05-05
  • C++利用數(shù)組(一維/二維)處理批量數(shù)據(jù)的方法

    C++利用數(shù)組(一維/二維)處理批量數(shù)據(jù)的方法

    對于簡單的問題,使用簡單的數(shù)據(jù)類型就可以了,但是對于有些需要處理的數(shù)據(jù),只用以上簡單的數(shù)據(jù)類型是不夠的,難以反映出數(shù)據(jù)的特點,也難以有效的進行處理,本文小編給大家介紹了C++利用數(shù)組(一維/二維)處理批量數(shù)據(jù)的方法,需要的朋友可以參考下
    2023-10-10
  • C++淺析析構(gòu)函數(shù)的特征

    C++淺析析構(gòu)函數(shù)的特征

    既然在創(chuàng)建對象時有構(gòu)造函數(shù)(給成員初始化),那么在銷毀對象時應(yīng)該還有一個清除成員變量數(shù)據(jù)的操作咯,析構(gòu)函數(shù)與構(gòu)造函數(shù)功能相反,析構(gòu)函數(shù)不是完成對象的銷毀,局部對象銷毀工作是由編譯器完成的。而對象在銷毀時會自動調(diào)用析構(gòu)函數(shù),完成類的一些資源清理工作
    2022-07-07
  • 溫故C語言內(nèi)存管理

    溫故C語言內(nèi)存管理

    這篇文章主要介紹了 C語言內(nèi)存管理的相關(guān)資料,本文給大家介紹的非常詳細,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2021-05-05
  • C++中結(jié)構(gòu)體和Json字符串互轉(zhuǎn)的問題詳解

    C++中結(jié)構(gòu)體和Json字符串互轉(zhuǎn)的問題詳解

    這篇文章主要給大家介紹了關(guān)于C++中結(jié)構(gòu)體和Json字符串互轉(zhuǎn)問題的相關(guān)資料,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2021-03-03
  • C++結(jié)構(gòu)體案例練習(xí)分享

    C++結(jié)構(gòu)體案例練習(xí)分享

    這篇文章主要和大家分享幾個C++?結(jié)構(gòu)體的案例練習(xí),幫助大家更好的理解和學(xué)習(xí)c++,感興趣的朋友可以了解下,希望能夠給你帶來幫助
    2022-04-04
  • Linux中使用VS Code編譯調(diào)試C++項目詳解

    Linux中使用VS Code編譯調(diào)試C++項目詳解

    最近因為項目的需求,需要在Linux下開發(fā)C++相關(guān)項目,經(jīng)過一番摸索最終實現(xiàn)了,下面這篇文章就給大家簡單總結(jié)了一下如何通過VS Code進行編譯調(diào)試的一些注意事項。有需要的朋友們可以參考借鑒,下面來跟著小編一起看看吧。
    2016-12-12

最新評論

金寨县| 涿鹿县| 仁化县| 施甸县| 宁都县| 锡林郭勒盟| 哈巴河县| 将乐县| 介休市| 佛坪县| 儋州市| 玉环县| 肇州县| 塔城市| 平远县| 平南县| 新建县| 长丰县| 吴桥县| 宜宾县| 宁化县| 盐池县| 栖霞市| 和林格尔县| 曲沃县| 琼海市| 建平县| 噶尔县| 京山县| 墨竹工卡县| 资阳市| 安新县| 即墨市| 万源市| 山丹县| 黎川县| 南丹县| 镇安县| 营口市| 清镇市| 临潭县|