<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
		>
<channel>
	<title>Comments for 同一屋檐下@dcshi</title>
	<atom:link href="http://www.dcshi.com/?feed=comments-rss2" rel="self" type="application/rss+xml" />
	<link>http://www.dcshi.com</link>
	<description></description>
	<lastBuildDate>Tue, 25 Oct 2011 05:40:17 +0000</lastBuildDate>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.2.1</generator>
	<item>
		<title>Comment on LINUX共享内存使用常见陷阱与分析 by dcshi</title>
		<link>http://www.dcshi.com/?p=79#comment-5</link>
		<dc:creator>dcshi</dc:creator>
		<pubDate>Tue, 25 Oct 2011 05:40:17 +0000</pubDate>
		<guid isPermaLink="false">http://www.dcshi.com/?p=79#comment-5</guid>
		<description>=== 关于shmdt和shmctl(shmid, IPC_RMID ===

shmdt -- 将进程内存空间的虚拟内存 和 内核空间的共享内存 脱离关系
每调用1次，attachCnt减1，当 attachCnt 为0时，内核空间的共享内存“才可以”被删除
[!] 进程退出时，会将之前 attach 的shm自动 detach。

所以，即使进程退出时进行了dt，但共享内存在内核中占用的空间并未释放。

RMID -- 删除ID，并尝试释放内核的相关空间（如果attachCnt为0才释放）
这是让id失效，进程不能再对该id进行attach，并尝试释放内核相应的空间。

探讨： 如果进程创建了共享内存，虽然可能显式或隐式地进行了dt，但如果没有调用 shmctl(id, IPC_RMID...)
该共享内存占用的内核空间应该是没有释放的。
换言之，不断地创建，而没有RMID，应该会造成相关内存泄漏，至少是ID泄漏。

佐证：
1) 《UNIX网络编程》卷2，第一章说明：
SysV的共享内存的持续性(persistency)是 kernel-persistency。 
即：如果不显式地删除（RMID)，那么只有等内核重启才能释放。
2） 之前邮件的程序也没有RMID，运行后，用ipcs 很容易看到ID 还存在！
3） APUE关于shm相关章节的程序里没有dt（因为进程退出时会自动dt），但进行了RMID

使用ipcs命令可以一直看到挂接数为0的共享内存，你这个时候用相同的ID去挂接还是能挂接上的，说明这个共享内存一直是存在的，这样说明不删除共享内存肯定会导致相关的内存泄漏。
另外，使用共享内存时候，最好不要使用进程退出来dt，应该自己程序来保证，还有一种情况，进程异常退出了，系统是不会去dt的，这时候就要依赖自己来保证了，去屏蔽系统异常信号，自己去dt并删除共享内存。</description>
		<content:encoded><![CDATA[<p>=== 关于shmdt和shmctl(shmid, IPC_RMID ===</p>
<p>shmdt &#8212; 将进程内存空间的虚拟内存 和 内核空间的共享内存 脱离关系<br />
每调用1次，attachCnt减1，当 attachCnt 为0时，内核空间的共享内存“才可以”被删除<br />
[!] 进程退出时，会将之前 attach 的shm自动 detach。</p>
<p>所以，即使进程退出时进行了dt，但共享内存在内核中占用的空间并未释放。</p>
<p>RMID &#8212; 删除ID，并尝试释放内核的相关空间（如果attachCnt为0才释放）<br />
这是让id失效，进程不能再对该id进行attach，并尝试释放内核相应的空间。</p>
<p>探讨： 如果进程创建了共享内存，虽然可能显式或隐式地进行了dt，但如果没有调用 shmctl(id, IPC_RMID&#8230;)<br />
该共享内存占用的内核空间应该是没有释放的。<br />
换言之，不断地创建，而没有RMID，应该会造成相关内存泄漏，至少是ID泄漏。</p>
<p>佐证：<br />
1) 《UNIX网络编程》卷2，第一章说明：<br />
SysV的共享内存的持续性(persistency)是 kernel-persistency。<br />
即：如果不显式地删除（RMID)，那么只有等内核重启才能释放。<br />
2） 之前邮件的程序也没有RMID，运行后，用ipcs 很容易看到ID 还存在！<br />
3） APUE关于shm相关章节的程序里没有dt（因为进程退出时会自动dt），但进行了RMID</p>
<p>使用ipcs命令可以一直看到挂接数为0的共享内存，你这个时候用相同的ID去挂接还是能挂接上的，说明这个共享内存一直是存在的，这样说明不删除共享内存肯定会导致相关的内存泄漏。<br />
另外，使用共享内存时候，最好不要使用进程退出来dt，应该自己程序来保证，还有一种情况，进程异常退出了，系统是不会去dt的，这时候就要依赖自己来保证了，去屏蔽系统异常信号，自己去dt并删除共享内存。</p>
]]></content:encoded>
	</item>
	<item>
		<title>Comment on LINUX共享内存使用常见陷阱与分析 by dcshi</title>
		<link>http://www.dcshi.com/?p=79#comment-4</link>
		<dc:creator>dcshi</dc:creator>
		<pubDate>Tue, 25 Oct 2011 05:33:35 +0000</pubDate>
		<guid isPermaLink="false">http://www.dcshi.com/?p=79#comment-4</guid>
		<description>========问题：
文中提到：
当多个进程都能创建共享内存的时候，如果key出现相同的情况，并且一个进程需要创建的共享内存的大小要比另外一个进程要创建的共享内存小，共享内存大的进程先创建共享内存，共享内存小的进程后创建共享内存，小共享内存的进程就会获取到大的共享内存进程的共享内存，并“修改其共享内存的大小”和内容，从而可能导致大的共享内存进程崩溃。

========根据以上描述：
1) 首先，进程A: shmid = shmget(key, 32*1024, IPC_CREAT&#124;(SHM_R&#124;SHM_W));
shmptr = shmat(shmid, 0, 0)
2) 然后，进程B：shmid = shmget(key, 16*1024, IPC_CREAT&#124;(SHM_R&#124;SHM_W));
因为key一样，所以进程A 创建的共享内存大小也就改成了 16*1024
3) 那么，进程A：memset(shmptr, 0, 32*1024) 将是非法操作

=======实际测试和结果：
测试环境： 基于Linux内核 2.6.16.46-0.12-xenpae-1024-18
测试结论： 进程A创建的共享内存大小并未改变，memset操作也没有问题。
原因：     进程中的共享内存是改进程虚拟内存空间到物理内存的映射，进程间互相独立。



相关数据：
parent: stat.size = 32768
parent: stat.size = 32768
child: x

[2]+ Done ./shm.exe

======相关代码：

&lt;pre&gt;
80 int main(int argc, void **argv)
81 {
82 int shmid;
83 char *shmptr;
84 key_t key = ftok(&quot;/usr/bin&quot;, 0x12345678);
85 int pid;
86 struct shmid_ds stat;
87 pid = fork();
88 if(0 == pid)//child
89 {
90 sleep(1); //等parent创建shm
91 shmid = shmget(key, 16*1024, IPC_CREAT&#124;SHM_R);
92 shmptr = shmat(shmid, 0, 0);
93 sleep(5);
94 printf(&quot;child: %c\n&quot;, *(char *)shmptr);
95 memset(shmptr, &#039;y&#039;, 32*1024); //这样memset 32k 也没有问题
96 
97 }
98 else if(0 &lt; pid) //parent
99 {
100 shmid = shmget(key, 32*1024, IPC_CREAT&#124;(SHM_R&#124;SHM_W));
101 shmptr = shmat(shmid, 0, 0);
102 shmctl(shmid, IPC_STAT, &amp;stat);
103 printf(&quot;parent: stat.size = %d\n&quot;, stat.shm_segsz);
104 sleep(3); //等child 修改size
105 shmctl(shmid, IPC_STAT, &amp;stat);
106 printf(&quot;parent: stat.size = %d\n&quot;, stat.shm_segsz);
107 memset(shmptr, &#039;x&#039;, 32*1024);
108 }
109 else
110 {
111 }
112 
113 return 0;
114 }
&lt;/pre&gt;</description>
		<content:encoded><![CDATA[<p>========问题：<br />
文中提到：<br />
当多个进程都能创建共享内存的时候，如果key出现相同的情况，并且一个进程需要创建的共享内存的大小要比另外一个进程要创建的共享内存小，共享内存大的进程先创建共享内存，共享内存小的进程后创建共享内存，小共享内存的进程就会获取到大的共享内存进程的共享内存，并“修改其共享内存的大小”和内容，从而可能导致大的共享内存进程崩溃。</p>
<p>========根据以上描述：<br />
1) 首先，进程A: shmid = shmget(key, 32*1024, IPC_CREAT|(SHM_R|SHM_W));<br />
shmptr = shmat(shmid, 0, 0)<br />
2) 然后，进程B：shmid = shmget(key, 16*1024, IPC_CREAT|(SHM_R|SHM_W));<br />
因为key一样，所以进程A 创建的共享内存大小也就改成了 16*1024<br />
3) 那么，进程A：memset(shmptr, 0, 32*1024) 将是非法操作</p>
<p>=======实际测试和结果：<br />
测试环境： 基于Linux内核 2.6.16.46-0.12-xenpae-1024-18<br />
测试结论： 进程A创建的共享内存大小并未改变，memset操作也没有问题。<br />
原因：     进程中的共享内存是改进程虚拟内存空间到物理内存的映射，进程间互相独立。</p>
<p>相关数据：<br />
parent: stat.size = 32768<br />
parent: stat.size = 32768<br />
child: x</p>
<p>[2]+ Done ./shm.exe</p>
<p>======相关代码：</p>
<pre class="wp-code-highlight prettyprint">
80 int main(int argc, void **argv)
81 {
82 int shmid;
83 char *shmptr;
84 key_t key = ftok(&quot;/usr/bin&quot;, 0x12345678);
85 int pid;
86 struct shmid_ds stat;
87 pid = fork();
88 if(0 == pid)//child
89 {
90 sleep(1); //等parent创建shm
91 shmid = shmget(key, 16*1024, IPC_CREAT|SHM_R);
92 shmptr = shmat(shmid, 0, 0);
93 sleep(5);
94 printf(&quot;child: %cn&quot;, *(char *)shmptr);
95 memset(shmptr, 'y', 32*1024); //这样memset 32k 也没有问题
96
97 }
98 else if(0 &lt; pid) //parent
99 {
100 shmid = shmget(key, 32*1024, IPC_CREAT|(SHM_R|SHM_W));
101 shmptr = shmat(shmid, 0, 0);
102 shmctl(shmid, IPC_STAT, &amp;stat);
103 printf(&quot;parent: stat.size = %dn&quot;, stat.shm_segsz);
104 sleep(3); //等child 修改size
105 shmctl(shmid, IPC_STAT, &amp;stat);
106 printf(&quot;parent: stat.size = %dn&quot;, stat.shm_segsz);
107 memset(shmptr, 'x', 32*1024);
108 }
109 else
110 {
111 }
112
113 return 0;
114 }
</pre>
]]></content:encoded>
	</item>
	<item>
		<title>Comment on 多进程如何不加锁读写文件队列 by kurs valut</title>
		<link>http://www.dcshi.com/?p=52#comment-3</link>
		<dc:creator>kurs valut</dc:creator>
		<pubDate>Thu, 20 Oct 2011 12:33:55 +0000</pubDate>
		<guid isPermaLink="false">http://www.dcshi.com/?p=52#comment-3</guid>
		<description>truly loved the article added to my favourites</description>
		<content:encoded><![CDATA[<p>truly loved the article added to my favourites</p>
]]></content:encoded>
	</item>
</channel>
</rss>

