共享內存 - shmget填坑記


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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM