1. 問題引出
最近有個項目,需要兩個程序之間傳遞大量的資料,是以考慮采用了共享
記憶體機制
+
信号同步
,兩個程序,筆者和另外一程式員開發,協定都定好了,開發很順利。
等到我們聯合調試的時候,問題出現了,筆者開發的程式,共享記憶體初始化一直失敗,那叫一個汗啊!
代碼如下:
/******************************************************************************
*函數名稱:yg_init_mem_share
*功能描述: 初始化共享記憶體(用于存放地圖校準資料)
*全局影響:無
*輸入:
*輸出:無
*傳回值:0:成功 -1:發送失敗
* 作者 日期 内容
* Jimmy 2018-10-16 建立
*
******************************************************************************/
void yg_init_mem_share(int size)
{
key_t key;
//int size = 1024*1024; //1M記憶體大小
//1. 建立共享記憶體
if(-1 == (key = ftok("/", 4)))
{
bv_loge("ftok failed [%d:%s]!", errno, strerror(errno));
bv_error_handle("ftok failed [%d:%s]!", errno, strerror(errno));
return ;
}
bv_logd("key=%#x!", key);
SHM_ID = shmget(key, (size_t)size, IPC_CREAT|0644);
if(-1 == SHM_ID)
{
bv_loge("Init the shared memory[%dKB] failed [%d:%s]!",size/1024, errno, strerror(errno));
bv_error_handle("Init the shared memory[%dKB] failed [%d:%s]!",size/1024, errno, strerror(errno));
}
else
{
bv_logd("Init the shared memory[%dKB] OK!", size/1000);
bv_file_log(g_tcp_fp, "Init the shared memory[%dKB] OK!", size/1000);
}
return ;
}
使用errno和strerror(errno)列印錯誤代碼:
Init the shared memory[100KB] failed [22:Invalid arguments]
2 問題解決
代碼反複讀了好幾遍,沒有發現問題,然後仔細閱讀了
man shmget
,看到了如下一句話:
EINVAL A new segment was to be created and size is less than SHMMIN or greater than SHMMAX.
EINVAL A segment for the given key exists, but size is greater than the size of that segment.
意思就是說:
shmget設定的size值,不能大于最大值SHMMAX和小于最小值SHMMIN
且如果key值對應的段已經存在,那麼後來使用shmget的size值要小于等于原來的值
然後詢問了一下那位程式猿,他設定的是20kB,我的是100kB,且他的設定為了開機啟動,是以每次出錯的都是我了,悲催!
3. 檢視SHMMIN和SHMMAX
cat /proc/sys/kernel/shmmin
cat /proc/sys/kernel/shmmax
或者
sysctl -a|grep shmmin
sysctl -a|grep shmmax
4. shmget使用方法
詳見:https://www.cnblogs.com/52php/p/5861372.html