﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>C++博客-键盘上的舞者-随笔分类-Linux</title><link>http://www.cppblog.com/Marcky/category/11045.html</link><description>My Email: marckywu@gmail.com</description><language>zh-cn</language><lastBuildDate>Sun, 23 Aug 2009 05:00:16 GMT</lastBuildDate><pubDate>Sun, 23 Aug 2009 05:00:16 GMT</pubDate><ttl>60</ttl><item><title>system V IPC —— 共享内存(下)</title><link>http://www.cppblog.com/Marcky/archive/2009/08/20/93911.html</link><dc:creator>Marcky</dc:creator><author>Marcky</author><pubDate>Thu, 20 Aug 2009 06:57:00 GMT</pubDate><guid>http://www.cppblog.com/Marcky/archive/2009/08/20/93911.html</guid><wfw:comment>http://www.cppblog.com/Marcky/comments/93911.html</wfw:comment><comments>http://www.cppblog.com/Marcky/archive/2009/08/20/93911.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/Marcky/comments/commentRss/93911.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/Marcky/services/trackbacks/93911.html</trackback:ping><description><![CDATA[使用共享内存和记录锁实例。本例中，父进程创建一段共享内存，然后向其中追加字符串"Parent"(在写入&#8220;Parent&#8221;的时候，采用一个字符一个字符的写入，目的是为了验证记录锁对父子进程同步的正确性)；子进程向共享内存中追加字符串&#8220;Child&#8221;（同样是一个一个的字符写入）。由于记录锁是针对文件的，所以得先创建一个空文件作为记录锁的操作对象，作为共享内存访问的辅助工具，如果一个进程对这个空文件加写锁成功后，就开始访问共享内存，访问结束就对文件解锁。<br><br>代码如下：<br>
<div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; background-color: #eeeeee; font-size: 13px; width: 98%;"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: #000000;">#include&nbsp;</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">stdio.h</span><span style="color: #000000;">&gt;</span><span style="color: #000000;"><br>#include&nbsp;</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">stdlib.h</span><span style="color: #000000;">&gt;</span><span style="color: #000000;"><br>#include&nbsp;</span><span style="color: #000000;">&lt;</span><span style="color: #0000ff;">string</span><span style="color: #000000;">.h</span><span style="color: #000000;">&gt;</span><span style="color: #000000;"><br><br>#include&nbsp;</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">unistd.h</span><span style="color: #000000;">&gt;</span><span style="color: #000000;"><br>#include&nbsp;</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">sys</span><span style="color: #000000;">/</span><span style="color: #000000;">types.h</span><span style="color: #000000;">&gt;</span><span style="color: #000000;"><br><br>#include&nbsp;</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">sys</span><span style="color: #000000;">/</span><span style="color: #000000;">wait.h</span><span style="color: #000000;">&gt;</span><span style="color: #000000;"><br>#include&nbsp;</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">fcntl.h</span><span style="color: #000000;">&gt;</span><span style="color: #000000;"><br><br>#include&nbsp;</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">sys</span><span style="color: #000000;">/</span><span style="color: #000000;">ipc.h</span><span style="color: #000000;">&gt;</span><span style="color: #000000;"><br>#include&nbsp;</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">sys</span><span style="color: #000000;">/</span><span style="color: #000000;">shm.h</span><span style="color: #000000;">&gt;</span><span style="color: #000000;"><br><br></span><span style="color: #0000ff;">#define</span><span style="color: #000000;">&nbsp;SHM_SIZE&nbsp;1024&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/*&nbsp;shared&nbsp;memory&nbsp;size(bytes)&nbsp;*/</span><span style="color: #000000;"><br></span><span style="color: #0000ff;">#define</span><span style="color: #000000;">&nbsp;SHM_MODE&nbsp;0600&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/*&nbsp;user&nbsp;read/write&nbsp;*/</span><span style="color: #000000;"><br><br></span><span style="color: #0000ff;">#define</span><span style="color: #000000;">&nbsp;WRITE_LOCK(fd)&nbsp;regLock((fd),&nbsp;F_SETLKW,&nbsp;F_WRLCK,&nbsp;0,&nbsp;SEEK_SET,&nbsp;0)&nbsp;</span><span style="color: #000000;"><br></span><span style="color: #0000ff;">#define</span><span style="color: #000000;">&nbsp;UN_LOCK(fd)&nbsp;regLock((fd),&nbsp;F_SETLK,&nbsp;F_UNLCK,&nbsp;0,&nbsp;SEEK_SET,&nbsp;0)&nbsp;</span><span style="color: #000000;"><br></span><span style="color: #008000;">/*</span><span style="color: #008000;">&nbsp;创建一个文件&nbsp;</span><span style="color: #008000;">*/</span><span style="color: #000000;"><br></span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;createFile()<br>{<br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;fd;<br><br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">if</span><span style="color: #000000;">&nbsp;(&nbsp;(fd&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;open(</span><span style="color: #000000;">"</span><span style="color: #000000;">/tmp/emptyfile4shm</span><span style="color: #000000;">"</span><span style="color: #000000;">,&nbsp;O_RDWR&nbsp;</span><span style="color: #000000;">|</span><span style="color: #000000;">&nbsp;O_CREAT,&nbsp;</span><span style="color: #000000;">0666</span><span style="color: #000000;">))&nbsp;</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">0</span><span style="color: #000000;">)&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;fprintf(stderr,&nbsp;</span><span style="color: #000000;">"</span><span style="color: #000000;">Create&nbsp;a&nbsp;empty&nbsp;file&nbsp;failed!\n</span><span style="color: #000000;">"</span><span style="color: #000000;">);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;exit(EXIT_FAILURE);<br>&nbsp;&nbsp;&nbsp;&nbsp;}<br><br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">return</span><span style="color: #000000;">&nbsp;fd;<br>}<br></span><span style="color: #008000;">/*</span><span style="color: #008000;">&nbsp;在文件fd上加锁或解锁</span><span style="color: #008000;">*/</span><span style="color: #000000;"><br></span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;regLock(</span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;fd,&nbsp;</span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;cmd,&nbsp;</span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;type,&nbsp;off_t&nbsp;offset,&nbsp;</span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;whence,&nbsp;off_t&nbsp;len)<br>{<br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">struct</span><span style="color: #000000;">&nbsp;flock&nbsp;</span><span style="color: #0000ff;">lock</span><span style="color: #000000;">;<br><br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">lock</span><span style="color: #000000;">.l_type&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;type;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">/*</span><span style="color: #008000;">&nbsp;lock&nbsp;type:&nbsp;F_RDLCK,&nbsp;F_WRLCK,&nbsp;F_UNLCK&nbsp;</span><span style="color: #008000;">*/</span><span style="color: #000000;"><br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">lock</span><span style="color: #000000;">.l_start&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;offset;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">/*</span><span style="color: #008000;">&nbsp;byte&nbsp;offset&nbsp;relative&nbsp;to&nbsp;l_whence&nbsp;</span><span style="color: #008000;">*/</span><span style="color: #000000;"><br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">lock</span><span style="color: #000000;">.l_whence&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;whence;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">/*</span><span style="color: #008000;">&nbsp;it's&nbsp;value&nbsp;:&nbsp;SEEK_SET,&nbsp;SEEK_CUR,&nbsp;SEEK_END&nbsp;</span><span style="color: #008000;">*/</span><span style="color: #000000;"><br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">lock</span><span style="color: #000000;">.l_len&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;len;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">/*</span><span style="color: #008000;">&nbsp;bytes&nbsp;(0&nbsp;means&nbsp;to&nbsp;EOF)&nbsp;</span><span style="color: #008000;">*/</span><span style="color: #000000;"><br><br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">return</span><span style="color: #000000;">&nbsp;fcntl(fd,&nbsp;cmd,&nbsp;</span><span style="color: #000000;">&amp;</span><span style="color: #0000ff;">lock</span><span style="color: #000000;">);<br>}<br><br></span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;main(</span><span style="color: #0000ff;">void</span><span style="color: #000000;">)<br>{<br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;shmid;<br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;filed;<br>&nbsp;&nbsp;&nbsp;&nbsp;pid_t&nbsp;pid;<br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">char</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">*</span><span style="color: #000000;">shmptr&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;NULL;<br><br>&nbsp;&nbsp;&nbsp;&nbsp;filed&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;createFile();<br><br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">if</span><span style="color: #000000;">&nbsp;(&nbsp;(shmid&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;shmget(IPC_PRIVATE,&nbsp;SHM_SIZE,&nbsp;SHM_MODE))&nbsp;</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">0</span><span style="color: #000000;">)&nbsp;{&nbsp;</span><span style="color: #008000;">/*</span><span style="color: #008000;">&nbsp;Create&nbsp;shared&nbsp;memory&nbsp;</span><span style="color: #008000;">*/</span><span style="color: #000000;"><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;fprintf(stderr,&nbsp;</span><span style="color: #000000;">"</span><span style="color: #000000;">Create&nbsp;shared&nbsp;memory&nbsp;failed!\n</span><span style="color: #000000;">"</span><span style="color: #000000;">);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;exit(EXIT_FAILURE);<br>&nbsp;&nbsp;&nbsp;&nbsp;}<br><br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">if</span><span style="color: #000000;">&nbsp;(&nbsp;(pid&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;fork())&nbsp;</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">0</span><span style="color: #000000;">)&nbsp;{&nbsp;&nbsp;</span><span style="color: #008000;">/*</span><span style="color: #008000;">&nbsp;Create&nbsp;a&nbsp;child&nbsp;process&nbsp;</span><span style="color: #008000;">*/</span><span style="color: #000000;"><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;fprintf(stderr,&nbsp;</span><span style="color: #000000;">"</span><span style="color: #000000;">Create&nbsp;child&nbsp;process&nbsp;failed!\n</span><span style="color: #000000;">"</span><span style="color: #000000;">);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;exit(EXIT_FAILURE);<br>&nbsp;&nbsp;&nbsp;&nbsp;}<br><br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">if</span><span style="color: #000000;">&nbsp;(pid&nbsp;</span><span style="color: #000000;">==</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">0</span><span style="color: #000000;">)&nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">/*</span><span style="color: #008000;">&nbsp;In&nbsp;child&nbsp;process&nbsp;</span><span style="color: #008000;">*/</span><span style="color: #000000;"><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">if</span><span style="color: #000000;">&nbsp;(&nbsp;(shmptr&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;shmat(shmid,&nbsp;</span><span style="color: #000000;">0</span><span style="color: #000000;">,&nbsp;</span><span style="color: #000000;">0</span><span style="color: #000000;">))&nbsp;</span><span style="color: #000000;">==</span><span style="color: #000000;">&nbsp;(</span><span style="color: #0000ff;">void</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">*</span><span style="color: #000000;">)</span><span style="color: #000000;">-</span><span style="color: #000000;">1</span><span style="color: #000000;">)&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;fprintf(stderr,&nbsp;</span><span style="color: #000000;">"</span><span style="color: #000000;">Attached&nbsp;shared&nbsp;memory&nbsp;failed!\n</span><span style="color: #000000;">"</span><span style="color: #000000;">);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;exit(EXIT_FAILURE);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">while</span><span style="color: #000000;">&nbsp;(</span><span style="color: #000000;">1</span><span style="color: #000000;">)&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;WRITE_LOCK(filed);&nbsp;&nbsp;</span><span style="color: #008000;">/*</span><span style="color: #008000;">&nbsp;add&nbsp;a&nbsp;write&nbsp;lock&nbsp;to&nbsp;filed&nbsp;</span><span style="color: #008000;">*/</span><span style="color: #000000;"><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">/*</span><span style="color: #008000;">&nbsp;shared&nbsp;memory&nbsp;剩余的空间不能存储"Child"字符串和结束符0时就退出循环&nbsp;</span><span style="color: #008000;">*/</span><span style="color: #000000;"><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">if</span><span style="color: #000000;">&nbsp;(SHM_SIZE&nbsp;</span><span style="color: #000000;">-</span><span style="color: #000000;">&nbsp;strlen(shmptr)&nbsp;</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">&nbsp;strlen(</span><span style="color: #000000;">"</span><span style="color: #000000;">Child</span><span style="color: #000000;">"</span><span style="color: #000000;">)&nbsp;</span><span style="color: #000000;">+</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">1</span><span style="color: #000000;">)&nbsp;</span><span style="color: #0000ff;">break</span><span style="color: #000000;">;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;strcat(shmptr,&nbsp;</span><span style="color: #000000;">"</span><span style="color: #000000;">C</span><span style="color: #000000;">"</span><span style="color: #000000;">);&nbsp;</span><span style="color: #008000;">/*</span><span style="color: #008000;">&nbsp;由于加了锁，每个Child将会连续出现&nbsp;</span><span style="color: #008000;">*/</span><span style="color: #000000;"><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;strcat(shmptr,&nbsp;</span><span style="color: #000000;">"</span><span style="color: #000000;">h</span><span style="color: #000000;">"</span><span style="color: #000000;">);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;strcat(shmptr,&nbsp;</span><span style="color: #000000;">"</span><span style="color: #000000;">i</span><span style="color: #000000;">"</span><span style="color: #000000;">);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;strcat(shmptr,&nbsp;</span><span style="color: #000000;">"</span><span style="color: #000000;">l</span><span style="color: #000000;">"</span><span style="color: #000000;">);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;strcat(shmptr,&nbsp;</span><span style="color: #000000;">"</span><span style="color: #000000;">d</span><span style="color: #000000;">"</span><span style="color: #000000;">);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;UN_LOCK(filed);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">/*</span><span style="color: #008000;">&nbsp;release&nbsp;lock&nbsp;</span><span style="color: #008000;">*/</span><span style="color: #000000;"><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;printf(</span><span style="color: #000000;">"</span><span style="color: #000000;">child&nbsp;process:\n\t%s\n</span><span style="color: #000000;">"</span><span style="color: #000000;">,&nbsp;shmptr);&nbsp;</span><span style="color: #008000;">/*</span><span style="color: #008000;">&nbsp;child&nbsp;process&nbsp;print&nbsp;shared&nbsp;memory&nbsp;</span><span style="color: #008000;">*/</span><span style="color: #000000;"><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;exit(</span><span style="color: #000000;">0</span><span style="color: #000000;">);<br>&nbsp;&nbsp;&nbsp;&nbsp;}<br><br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">/*</span><span style="color: #008000;">&nbsp;In&nbsp;parent&nbsp;process&nbsp;</span><span style="color: #008000;">*/</span><span style="color: #000000;"><br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">if</span><span style="color: #000000;">&nbsp;(&nbsp;(shmptr&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;shmat(shmid,&nbsp;</span><span style="color: #000000;">0</span><span style="color: #000000;">,&nbsp;</span><span style="color: #000000;">0</span><span style="color: #000000;">))&nbsp;</span><span style="color: #000000;">==</span><span style="color: #000000;">&nbsp;(</span><span style="color: #0000ff;">void</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">*</span><span style="color: #000000;">)</span><span style="color: #000000;">-</span><span style="color: #000000;">1</span><span style="color: #000000;">)&nbsp;{&nbsp;</span><span style="color: #008000;">/*</span><span style="color: #008000;">&nbsp;Attached&nbsp;shared&nbsp;memory&nbsp;</span><span style="color: #008000;">*/</span><span style="color: #000000;"><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;fprintf(stderr,&nbsp;</span><span style="color: #000000;">"</span><span style="color: #000000;">Attached&nbsp;shared&nbsp;memory&nbsp;failed!\n</span><span style="color: #000000;">"</span><span style="color: #000000;">);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;exit(EXIT_FAILURE);<br>&nbsp;&nbsp;&nbsp;&nbsp;}<br>&nbsp;&nbsp;&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">while</span><span style="color: #000000;">&nbsp;(</span><span style="color: #000000;">1</span><span style="color: #000000;">)&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;WRITE_LOCK(filed);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">/*</span><span style="color: #008000;">&nbsp;shared&nbsp;memory&nbsp;剩余的空间不能存储"Parent"字符串和结束符0时就退出循环&nbsp;</span><span style="color: #008000;">*/</span><span style="color: #000000;"><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">if</span><span style="color: #000000;">&nbsp;(SHM_SIZE&nbsp;</span><span style="color: #000000;">-</span><span style="color: #000000;">&nbsp;strlen(shmptr)&nbsp;</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">&nbsp;strlen(</span><span style="color: #000000;">"</span><span style="color: #000000;">Parent</span><span style="color: #000000;">"</span><span style="color: #000000;">)&nbsp;</span><span style="color: #000000;">+</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">1</span><span style="color: #000000;">)&nbsp;</span><span style="color: #0000ff;">break</span><span style="color: #000000;">;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;strcat(shmptr,&nbsp;</span><span style="color: #000000;">"</span><span style="color: #000000;">P</span><span style="color: #000000;">"</span><span style="color: #000000;">);</span><span style="color: #008000;">/*</span><span style="color: #008000;">&nbsp;由于加了锁，每个Parent将会连续出现&nbsp;</span><span style="color: #008000;">*/</span><span style="color: #000000;"><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;strcat(shmptr,&nbsp;</span><span style="color: #000000;">"</span><span style="color: #000000;">a</span><span style="color: #000000;">"</span><span style="color: #000000;">);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;strcat(shmptr,&nbsp;</span><span style="color: #000000;">"</span><span style="color: #000000;">r</span><span style="color: #000000;">"</span><span style="color: #000000;">);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;strcat(shmptr,&nbsp;</span><span style="color: #000000;">"</span><span style="color: #000000;">e</span><span style="color: #000000;">"</span><span style="color: #000000;">);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;strcat(shmptr,&nbsp;</span><span style="color: #000000;">"</span><span style="color: #000000;">n</span><span style="color: #000000;">"</span><span style="color: #000000;">);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;strcat(shmptr,&nbsp;</span><span style="color: #000000;">"</span><span style="color: #000000;">t</span><span style="color: #000000;">"</span><span style="color: #000000;">);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;UN_LOCK(filed);<br>&nbsp;&nbsp;&nbsp;&nbsp;}<br>&nbsp;&nbsp;&nbsp;&nbsp;printf(</span><span style="color: #000000;">"</span><span style="color: #000000;">parent&nbsp;process:\n\t%s\n</span><span style="color: #000000;">"</span><span style="color: #000000;">,&nbsp;shmptr);&nbsp;</span><span style="color: #008000;">/*</span><span style="color: #008000;">&nbsp;parent&nbsp;print&nbsp;shared&nbsp;memory&nbsp;</span><span style="color: #008000;">*/</span><span style="color: #000000;"><br><br>&nbsp;&nbsp;&nbsp;&nbsp;wait(</span><span style="color: #000000;">0</span><span style="color: #000000;">);<br>&nbsp;&nbsp;&nbsp;&nbsp;exit(</span><span style="color: #000000;">0</span><span style="color: #000000;">);<br>}<br>&nbsp;&nbsp;&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;<br></span></div>
<br><br><img src ="http://www.cppblog.com/Marcky/aggbug/93911.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/Marcky/" target="_blank">Marcky</a> 2009-08-20 14:57 <a href="http://www.cppblog.com/Marcky/archive/2009/08/20/93911.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>system V IPC —— 共享内存(上)</title><link>http://www.cppblog.com/Marcky/archive/2009/08/20/93909.html</link><dc:creator>Marcky</dc:creator><author>Marcky</author><pubDate>Thu, 20 Aug 2009 06:48:00 GMT</pubDate><guid>http://www.cppblog.com/Marcky/archive/2009/08/20/93909.html</guid><wfw:comment>http://www.cppblog.com/Marcky/comments/93909.html</wfw:comment><comments>http://www.cppblog.com/Marcky/archive/2009/08/20/93909.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/Marcky/comments/commentRss/93909.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/Marcky/services/trackbacks/93909.html</trackback:ping><description><![CDATA[共享内存允许多个进程共享一给定的存储区。因为数据不需要在两个进程之间进行copy，所以这是最快的一种IPC。使用共享内存技术的时候，需要掌握好的是多个进程之间如何同步。信号量和记录锁可以用来实现共享内存的多个进程之间的同步。<br><br>linux内核定义的shared memory结构shmid_ds如下：<br>
<div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; background-color: #eeeeee; font-size: 13px; width: 98%;"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: #0000ff;">struct</span><span style="color: #000000;">&nbsp;shmid_ds&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">struct</span><span style="color: #000000;">&nbsp;ipc_perm&nbsp;&nbsp;shm_perm;&nbsp;&nbsp;</span><span style="color: #008000;">/*</span><span style="color: #008000;">权限</span><span style="color: #008000;">*/</span><span style="color: #000000;"><br>&nbsp;&nbsp;&nbsp;&nbsp;size_t&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;shm_segsz;&nbsp;</span><span style="color: #008000;">/*</span><span style="color: #008000;">大小</span><span style="color: #008000;">*/</span><span style="color: #000000;"><br>&nbsp;&nbsp;&nbsp;&nbsp;pid_t&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;shm_lpid;&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;pid_t&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;shm_cpid;&nbsp;&nbsp;</span><span style="color: #008000;">/*</span><span style="color: #008000;">创建者pid</span><span style="color: #008000;">*/</span><span style="color: #000000;"><br>&nbsp;&nbsp;&nbsp;&nbsp;shmatt_t&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;shm_nattch;</span><span style="color: #008000;">/*</span><span style="color: #008000;">连接到此段内存的进程数</span><span style="color: #008000;">*/</span><span style="color: #000000;"><br>&nbsp;&nbsp;&nbsp;&nbsp;time_t&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;shm_atime;<br>&nbsp;&nbsp;&nbsp;&nbsp;time_t&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;shm_dtime;<br>&nbsp;&nbsp;&nbsp;&nbsp;time_t&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;shm_ctime;<br>&nbsp;&nbsp;&nbsp;&nbsp;<img src="http://www.cppblog.com/Images/dot.gif"><br>};</span></div>
<br>1、创建或使用一段共享内存使用shmget函数，此函数将返回共享内存标示符。<br>
<div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; background-color: #eeeeee; font-size: 13px; width: 98%;"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: #000000;">#include&nbsp;</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">sys</span><span style="color: #000000;">/</span><span style="color: #000000;">shm.h</span><span style="color: #000000;">&gt;</span><span style="color: #000000;"><br></span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;shmget(key_t key,&nbsp;size_t&nbsp;size,&nbsp;</span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;flag);</span></div>
如果key取值为IPC_PRIVATE或者key当前为和特定类型的IPC结构相结合，并且flag指定了IPC_CREAT位，则创建一个新的share memory结构。<br>size为共享内存段的长度（字节）。<br><br>2、对一个共享内存段进行操作使用shmctl。<br>
<div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; background-color: #eeeeee; font-size: 13px; width: 98%;"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: #000000;">#include&nbsp;</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">sys</span><span style="color: #000000;">/</span><span style="color: #000000;">shm.h</span><span style="color: #000000;">&gt;</span><span style="color: #000000;"><br></span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;shmctl(</span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;shmid,&nbsp;</span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;cmd,&nbsp;</span><span style="color: #0000ff;">struct</span><span style="color: #000000;">&nbsp;shmid_ds&nbsp;</span><span style="color: #000000;">*</span><span style="color: #000000;">buf);</span></div>
shmid指定需要操作的shared memory<br>cmd指定需要进行的操作<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; IPC_STAT取得此段的shmid_ds结构放入buf中。<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; IPC_SET用buf的值设置此段中的：shm_perm.uid，shm_perm.gid，shm_perm.mode。<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; IPC_RMID从系统中删除此共享内存段。<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; SHM_LOCK将共享内存锁定到内存中。<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; SHM_UNLOCK解锁共享内存段。<br><br>3、将一个共享内存段连接到自己的地址空间使用shmat：<br>
<div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; background-color: #eeeeee; font-size: 13px; width: 98%;"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: #000000;">#include&nbsp;</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">sys</span><span style="color: #000000;">/</span><span style="color: #000000;">shm.h</span><span style="color: #000000;">&gt;</span><span style="color: #000000;"><br></span><span style="color: #0000ff;">void</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">*</span><span style="color: #000000;">shmat(</span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;shmid,&nbsp;</span><span style="color: #0000ff;">const</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">void</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">*</span><span style="color: #000000;">addr,&nbsp;</span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;flag);</span></div>
推荐addr取0值，将此段连接到内核选择的第一个可用的地址上。增加程序的可移植性。<br><br>4、对共享内存操作结束后，要脱离该段用shmdt：<br>
<div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; background-color: #eeeeee; font-size: 13px; width: 98%;"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: #000000;">#include&nbsp;</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">sys</span><span style="color: #000000;">/</span><span style="color: #000000;">shm.h</span><span style="color: #000000;">&gt;</span><span style="color: #000000;"><br></span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;shmdt(</span><span style="color: #0000ff;">void</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">*</span><span style="color: #000000;">addr);</span></div>
addr是shmat的返回值。<br><br> <img src ="http://www.cppblog.com/Marcky/aggbug/93909.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/Marcky/" target="_blank">Marcky</a> 2009-08-20 14:48 <a href="http://www.cppblog.com/Marcky/archive/2009/08/20/93909.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Linux命令:(){ :|:&amp; };:分析</title><link>http://www.cppblog.com/Marcky/archive/2009/06/30/88908.html</link><dc:creator>Marcky</dc:creator><author>Marcky</author><pubDate>Tue, 30 Jun 2009 08:46:00 GMT</pubDate><guid>http://www.cppblog.com/Marcky/archive/2009/06/30/88908.html</guid><wfw:comment>http://www.cppblog.com/Marcky/comments/88908.html</wfw:comment><comments>http://www.cppblog.com/Marcky/archive/2009/06/30/88908.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/Marcky/comments/commentRss/88908.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/Marcky/services/trackbacks/88908.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 有人说:(){ :|:& };: 命令就是一个系统炸弹。在linux的shell里执行此命令将会不停的创建新的进程，直到系统挂掉为止。刚看到这个怪七怪八的命令，也是完全不知所云，在水木高手解释后，总算是明白了。&nbsp;&nbsp;<a href='http://www.cppblog.com/Marcky/archive/2009/06/30/88908.html'>阅读全文</a><img src ="http://www.cppblog.com/Marcky/aggbug/88908.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/Marcky/" target="_blank">Marcky</a> 2009-06-30 16:46 <a href="http://www.cppblog.com/Marcky/archive/2009/06/30/88908.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>