shm進程間通信失敗了!!!

      網友投稿 685 2025-04-01

      稍安勿躁。

      先解決問題

      如果你是在網上輾轉而不得其解,那就來我這兒吧。

      之前那篇寫的比較急,講的還是蠻有條理的,就是東西少了點,這篇一次性寫完。

      那天,我和共享內存、shmid不眠不休只吃一點喝一點奮戰了十個小時,只為了把我的項目進度趕在大家前面,卻被進程間通信始終無法打通而攔住。解決問題之后,有感而作。

      如果放在今天,我會選擇采用TCP流協議的方式來進行進程間通信,詳情:你會不會分布式系統進程間通信

      不過我們現在講的是shm,好。

      以下內容基于在一個進程里至少準備掛兩個共享內存,一個用來發,一個用來收

      既然用到shm,那自然和key值要打交道。

      key值有fotk函數生成,如果對ftok函數不熟,有空可以看一下這篇:ftok

      講的是極好的,不是我寫的。

      我遇到的第一個問題,是:

      不同參數的ftok生成同樣的shmid值

      為什么呢?不知道。

      但是我還不算傻,至少知道做個demo把key值打印出來看,全是-1。

      ftok的第一個參數得是有效的文件路徑。

      看了上面那篇文章之后,我將代碼進行了修改,接下來就遇到了第二個問題:

      同樣參數的ftok函數生成了不同的key值

      這個就不好找咯,上面那個還能在網上找到點蛛絲馬跡,這個要是找到希望能在下面給我留個網址,感激不盡。

      這個就不好找咯,上面那個還能在網上找到點蛛絲馬跡,這個要是找到希望能在下面給我留個網址,感激不盡。

      這個就要分兩種情況了(我遇到兩種),第一種就是代碼的問題,剛開始我寫的花里胡哨的,后面老實了,拿到key值之后直接就shm_get, 這下shmid也老實了,不過還是會差,因為key值會偏差一點。

      第二種情況,

      其實問題也很簡單,就是目錄的差別。如果你用的是絕對目錄那就比較好,但是如果給ftok傳參傳的是相對目錄,而你運行的兩個執行文件所在的目錄又不同,那么ftok計算key值時從當前進程所在目錄出發,自然是會有偏差的。

      怎么辦?怎么辦?

      小事情,這里有兩個方法:

      1、將兩個執行文件放在統一目錄底下,方法是好方法,不過最好你得會寫Makefile

      2、使用絕對路徑,其實這個方法也能另辟蹊徑,什么呢, / ,就是這個斜杠,杠杠的絕對路徑

      shm共享內存

      創建或打開共享內存

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

      1

      2

      3

      4

      參數不釋義,后面有例子

      掛載共享內存

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

      1

      2

      3

      4

      分離共享內存

      #include int shmdt(const void *shmaddr);

      1

      2

      3

      控制共享內存

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

      1

      2

      3

      4

      示例

      #include "f_shm.h" #include #include #include #include #include #include #include #include #include #include typedef struct shmhead_st { int shmid; // 共享內存ID unsigned int blksize; // 塊大小 unsigned int blocks; // 總塊數 unsigned int rd_index; // 讀索引 unsigned int wr_index; // 寫索引 //必須放在共享內存內部才行 sem_t sem_mutex; // 用來互斥用的信號量 sem_t sem_full; // 用來控制共享內存是否滿的信號量 sem_t sem_empty; // 用來控制共享內存是否空的信號量 }shmhead_t; F_Shm::F_Shm(key_t key, int blksize, int blocks) { this->open_shm(key, blksize, blocks); } F_Shm::F_Shm() { shmhead = NULL; payload = NULL; open = false; } F_Shm::~F_Shm() { this->close_shm(); } //返回頭地址 bool F_Shm::creat_shm(key_t key, int blksize, int blocks) { int shmid = 0; //1. 查看是否已經存在共享內存,如果有則刪除舊的 shmid = shmget(key, 0, 0); if (shmid != -1) { shmctl(shmid, IPC_RMID, NULL); // 刪除已經存在的共享內存 } //2. 創建共享內存 shmid = shmget(key, sizeof(shmhead_t) + blksize*blocks, 0666 | IPC_CREAT | IPC_EXCL); if(shmid == -1) { ERR_EXIT("shmget"); } printf("Create shmid=%d size=%u \n", shmid, sizeof(shmhead_t) + blksize*blocks); //3.連接共享內存 shmhead = shmat(shmid, (void*)0, 0); //連接共享內存 if(shmhead == (void*)-1) { ERR_EXIT("shmat"); } memset(shmhead, 0, sizeof(shmhead_t) + blksize*blocks); //初始化 //4. 初始化共享內存信息 shmhead_t * pHead = (shmhead_t *)(shmhead); pHead->shmid = shmid; //共享內存shmid pHead->blksize = blksize; //共享信息寫入 pHead->blocks = blocks; //寫入每塊大小 pHead->rd_index = 0; //一開始位置都是第一塊 pHead->wr_index = 0; // sem_init(&pHead->sem_mutex, 1, 1); // 第一個1表示可以跨進程共享,第二個1表示初始值 sem_init(&pHead->sem_empty, 1, 0); // 第一個1表示可以跨進程共享,第二個0表示初始值 sem_init(&pHead->sem_full, 1, blocks);// 第一個1表示可以跨進程共享,第二個blocks表示初始值 //5. 填充控制共享內存的信息 payload = (char *)(pHead + 1); //實際負載起始位置 open = true; return true; } void F_Shm::dsy_shm() { shmhead_t *pHead = (shmhead_t *)shmhead; int shmid = pHead->shmid; //刪除信號量 sem_destroy (&pHead->sem_full); sem_destroy (&pHead->sem_empty); sem_destroy (&pHead->sem_mutex); shmdt(shmhead); //共享內存脫離 //銷毀共享內存 if(shmctl(shmid, IPC_RMID, 0) == -1) //刪除共享內存 { printf("Delete shmid=%d \n", shmid); ERR_EXIT("shmctl rm"); } shmhead = NULL; payload = NULL; open = false; } void F_Shm::Destroy(key_t key) { int shmid = 0; //1. 查看是否已經存在共享內存,如果有則刪除舊的 shmid = shmget(key, 0, 0); if (shmid != -1) { printf("Delete shmid=%d \n", shmid); shmctl(shmid, IPC_RMID, NULL); // 刪除已經存在的共享內存 } } //返回頭地址 bool F_Shm::open_shm(key_t key, int blksize, int blocks) { int shmid; this->close_shm(); //1. 查看是否已經存在共享內存,如果有則刪除舊的 shmid = shmget(key, 0, 0); if (shmid == -1) { return this->creat_shm(key, blksize, blocks); } //2.連接共享內存 shmhead = shmat(shmid, (void*)0, 0); //連接共享內存 if(shmhead == (void*)-1) { ERR_EXIT("shmat"); } printf("Open shmid=%d size=%u \n", shmid, sizeof(shmhead_t) + blksize*blocks); //3. 填充控制共享內存的信息 payload = (char *)((shmhead_t *)shmhead + 1); //實際負載起始位置 open = true; return true; } //關閉共享內存 void F_Shm::close_shm(void) { if(open) { shmdt(shmhead); //共享內存脫離 shmhead = NULL; payload = NULL; open = false; } } void F_Shm::write_into_shm(const void *buf) { shmhead_t *pHead = (shmhead_t *)shmhead; sem_wait(&pHead->sem_full); //是否有資源寫? 可用寫資源-1 sem_wait(&pHead->sem_mutex); //是否有人正在寫? printf("write to shm[%d] index %d \n", pHead->shmid, pHead->rd_index); memcpy(payload + (pHead->wr_index) * (pHead->blksize), buf, pHead->blksize); pHead->wr_index = (pHead->wr_index+1) % (pHead->blocks); //寫位置偏移 sem_post(&pHead->sem_mutex); //解除互斥 sem_post(&pHead->sem_empty); //可用讀資源+1 } void F_Shm::read_from_shm(void *buf) { shmhead_t *pHead = (shmhead_t *)shmhead; sem_wait(&pHead->sem_empty); //檢測寫資源是否可用 printf("read from shm[%d] index %d \n", pHead->shmid, pHead->rd_index); memcpy(buf, payload + (pHead->rd_index) * (pHead->blksize), pHead->blksize); //讀位置偏移 pHead->rd_index = (pHead->rd_index+1) % (pHead->blocks); sem_post(&pHead->sem_full); //增加可寫資源 }

      1

      2

      3

      4

      5

      6

      7

      8

      9

      10

      11

      12

      13

      14

      15

      16

      17

      18

      19

      20

      21

      22

      23

      24

      25

      26

      27

      28

      29

      30

      31

      32

      33

      34

      35

      36

      37

      38

      39

      40

      41

      42

      43

      44

      45

      46

      47

      48

      49

      50

      51

      52

      53

      54

      55

      56

      57

      58

      shm進程間通信失敗了!!!

      59

      60

      61

      62

      63

      64

      65

      66

      67

      68

      69

      70

      71

      72

      73

      74

      75

      76

      77

      78

      79

      80

      81

      82

      83

      84

      85

      86

      87

      88

      89

      90

      91

      92

      93

      94

      95

      96

      97

      98

      99

      100

      101

      102

      103

      104

      105

      106

      107

      108

      109

      110

      111

      112

      113

      114

      115

      116

      117

      118

      119

      120

      121

      122

      123

      124

      125

      126

      127

      128

      129

      130

      131

      132

      133

      134

      135

      136

      137

      138

      139

      140

      141

      142

      143

      144

      145

      146

      147

      148

      149

      150

      151

      152

      153

      154

      155

      156

      157

      158

      159

      160

      161

      162

      163

      164

      165

      166

      167

      168

      169

      170

      171

      172

      173

      174

      175

      176

      177

      178

      179

      180

      181

      182

      183

      184

      185

      186

      187

      188

      189

      190

      191

      192

      193

      194

      195

      196

      197

      198

      任務調度

      版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。

      版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。

      上一篇:什么是商業智能?
      下一篇:多線程系列二》不理解future怎么能有future?
      相關文章
      亚洲欧美日本韩国| 亚洲一区二区影视| 免费观看亚洲人成网站| 日韩亚洲国产高清免费视频| 亚洲国产av一区二区三区丶| 亚洲精品电影天堂网| 亚洲综合自拍成人| 亚洲AV日韩AV永久无码久久| 亚洲AV永久青草无码精品| 中文亚洲AV片在线观看不卡| 夜夜春亚洲嫩草影院| 中文字幕亚洲一区二区va在线| 在线精品亚洲一区二区三区| 亚洲欧洲日本在线| 亚洲中文字幕第一页在线| 国产亚洲美女精品久久久| 亚洲色精品vr一区二区三区| 国产亚洲精品自在久久| 久久精品亚洲综合专区| 无码乱人伦一区二区亚洲| 水蜜桃亚洲一二三四在线| 久久久国产精品亚洲一区| 亚洲日韩乱码中文无码蜜桃| 亚洲国产精品网站久久| 自拍日韩亚洲一区在线| 亚洲精品人成网在线播放影院| 亚洲综合av一区二区三区| 亚洲AV无码专区在线电影成人| 国产精品久久亚洲一区二区| 亚洲日韩中文字幕日韩在线| 亚洲国产精品一区二区第一页免| 久久亚洲中文字幕精品一区四| 亚洲乱码一区二区三区在线观看 | 亚洲色欲色欱wwW在线| 亚洲中文字幕无码爆乳app| 亚洲国产精品无码观看久久| 亚洲区不卡顿区在线观看| 国产aⅴ无码专区亚洲av麻豆| 亚洲国产成人精品不卡青青草原| 久久久亚洲欧洲日产国码二区| 亚洲国产美女精品久久|