- 论坛徽章:
- 0
|
关于SystemV 共享存储的问题.
对无双的热心表示感谢,但又对无双的不负责任的态度感到婉惜。
我从你前一次的回贴看不出什么答案.相信很多人也看不出什么答案。说老实话。我觉得这个坛子风气越来越差,很多人不懂装懂误导别人。copy paste的作法随处可见,真正解释问题,分析原因的内容少之又少?要不含糊其词,故作深沉.
这两天看了一下FreeBSD关于ipc的源代码,也查了一些资料。结果并不是你所说的posix理解偏差。“有的系统的实现的话可能不会实现按进程限制,而只是限制总数目”不知你说的是什么系统?
在FB源文件sysv_shm.c中找到关于shmseg和shmmni的变量:
- TUNABLE_INT("kern.ipc.shmmni", &shminfo.shmmni);
- TUNABLE_INT("kern.ipc.shmseg", &shminfo.shmseg);
复制代码
发现在shmget函数中没有出现检查shminof.shmseg的地方.只是在开头检查了一下
shmmin,shmmax,shmmni,没有对shmseg进行检查。代码如下
- if (uap->;size < shminfo.shmmin || uap->;size >; shminfo.shmmax)
- return EINVAL;
- if (shm_nused >;= shminfo.shmmni) /* any shmids left? */
- return ENOSPC;
复制代码
但在shmat函数中却发现了检查shmseg的代码
- if (i >;= shminfo.shmseg)
- return EMFILE;
复制代码
编程测试
- #include <sys/types.h>;
- #include <unistd.h>;
- #include <sys/ipc.h>;
- #include <sys/shm.h>;
- #define MAXLIST 1000
- int shmlist[MAXLIST];
- char *shmpt[MAXLIST];
- int main(int argc,char **argv)
- {
- int i,n;
- for(i=0;i<MAXLIST;i++){
- if((shmlist[i]=shmget(IPC_PRIVATE,1,SHM_R|SHM_W))<0) break;
- if((shmpt[i]=shmat(shmlist[i],0,0))==(void*) -1) { //增加shmat
- warn("break at shmat\n");
- break;
- }
- printf("Your Limits is:%d\n",i);
- for(n=0;n<=i;n++){
- shmdt(shmpt[n]);
- if(shmctl(shmlist[n],IPC_RMID,NULL)<0)
- errx(1,"error when remove share memory id.\n");
- }
- exit(0);
- }
复制代码
编译运行后的结果果然是kern.ipc.shmseg设定的值128
$ ./a.out
a.out: break at shmat: Too many open files
Your Limits is:128
$
查找了很多资料,发现很多关于shmseg和shmmni之间区别的翻译讲得含糊不清,而且都不规范。大多如你所paste的那样
- SHMSEG 每进程最大共享内存段数量 只需要 1 个段,不过缺省比这高得多.
- SHMMNI 系统范围最大共享内存段数量 类似 SHMSEG + 用于其他应用的空间
复制代码
其实shmseg真正限制的是进程可以用shmat连接的内存段的数量,而不是限制用shmget创建内存段的数量.在linux 及solaris上测试结果也是如此。 |
|