天天看點

将poll程式改為epoll實作

原執行個體在APUE(第三版)17.2 UNIX域套接字

1、使用UNIX與套接字輪詢XSI消息隊列(poll版,原版)

<code>#include "apue.h"</code>

<code>#include &lt;poll.h&gt;</code>

<code>#include &lt;pthread.h&gt;</code>

<code>#include &lt;sys/msg.h&gt;</code>

<code>#include &lt;sys/socket.h&gt;</code>

<code>#define NQ         3       //隊列的數量</code>

<code>#define MAXMSZ     512     //消息的最大長度</code>

<code>#define KEY            0x123   //消息隊列的第一個key值</code>

<code>struct</code> <code>threadinfo {</code>

<code>    </code><code>int</code> <code>qid;</code>

<code>    </code><code>int</code> <code>fd;</code>

<code>};</code>

<code>struct</code> <code>mymesg {</code>

<code>    </code><code>long</code> <code>mtype;</code>

<code>    </code><code>char</code> <code>mtext[MAXMSZ];</code>

<code>void</code> <code>*helper(</code><code>void</code> <code>*arg)</code>

<code>{</code>

<code>    </code><code>int</code> <code>n;</code>

<code>    </code><code>struct</code> <code>mymesg m;</code>

<code>    </code><code>struct</code> <code>threadinfo *tip = arg;</code>

<code>    </code><code>for</code> <code>(;;) {</code>

<code>        </code><code>printf</code><code>(</code><code>"helper qid %d, fd %d, tid %u\n"</code><code>, tip-&gt;qid, tip-&gt;fd, (unsigned)pthread_self());</code>

<code>        </code><code>memset</code><code>(&amp;m, 0, </code><code>sizeof</code><code>(m));</code>

<code>        </code><code>if</code> <code>((n = msgrcv(tip-&gt;qid, &amp;m, MAXMSZ, 0, MSG_NOERROR)) &lt; 0) {</code>

<code>            </code><code>err_sys(</code><code>"msgrcv error"</code><code>);</code>

<code>        </code><code>}</code>

<code>        </code><code>if</code> <code>(write(tip-&gt;fd, m.mtext, n) &lt; 0) {</code>

<code>            </code><code>err_sys(</code><code>"write error"</code><code>);</code>

<code>    </code><code>}</code>

<code>}</code>

<code>int</code> <code>main()</code>

<code>    </code><code>int</code> <code>i, n, err;</code>

<code>    </code><code>int</code> <code>fd[2];</code>

<code>    </code><code>int</code> <code>qid[NQ];</code>

<code>    </code><code>struct</code> <code>pollfd pfd[NQ];</code>

<code>    </code><code>struct</code> <code>threadinfo ti[NQ];</code>

<code>    </code><code>pthread_t tid[NQ];</code>

<code>    </code><code>char</code> <code>buf[MAXMSZ];</code>

<code>    </code><code>for</code> <code>(i = 0; i &lt; NQ; ++i) {</code>

<code>        </code><code>if</code> <code>((qid[i] = msgget((KEY+i), IPC_CREAT|0666)) &lt; 0) { </code><code>//建立一個新隊列</code>

<code>            </code><code>err_sys(</code><code>"msgget error"</code><code>);</code>

<code>        </code><code>printf</code><code>(</code><code>"queue %d ID is %d\n"</code><code>, i, qid[i]);</code>

<code>        </code><code>if</code> <code>(socketpair(AF_UNIX, SOCK_DGRAM, 0, fd) &lt; 0) { </code><code>//建立UNXI域套接字(fd管道)</code>

<code>            </code><code>err_sys(</code><code>"socketpair error"</code><code>);</code>

<code>        </code><code>printf</code><code>(</code><code>"fd[0]:%d\n"</code><code>, fd[0]);</code>

<code>        </code><code>printf</code><code>(</code><code>"fd[1]:%d\n"</code><code>, fd[1]);</code>

<code>        </code><code>pfd[i].fd = fd[0];</code>

<code>        </code><code>pfd[i].events = POLLIN;</code>

<code>        </code><code>ti[i].qid = qid[i];</code>

<code>        </code><code>ti[i].fd = fd[1];</code>

<code>        </code><code>if</code> <code>((err = pthread_create(&amp;tid[i], NULL, helper, &amp;ti[i])) != 0) {  </code><code>//建立線程</code>

<code>            </code><code>err_exit(err, </code><code>"pthread_create error"</code><code>);</code>

<code>        </code><code>if</code> <code>(poll(pfd, NQ, -1) &lt; 0) {   </code><code>//等待事件發生</code>

<code>            </code><code>err_sys(</code><code>"poll error"</code><code>);</code>

<code>        </code><code>for</code> <code>(i = 0; i &lt; NQ; ++i) {</code>

<code>            </code><code>//printf("i:%d\n", i);</code>

<code>            </code><code>if</code> <code>(pfd[i].revents &amp; POLLIN) {</code>

<code>                </code><code>if</code> <code>((n = read(pfd[i].fd, buf, </code><code>sizeof</code><code>(buf))) &lt; 0) {</code>

<code>                    </code><code>err_sys(</code><code>"read error"</code><code>);</code>

<code>                </code><code>}</code>

<code>                </code><code>buf[n] = 0;</code>

<code>                </code><code>printf</code><code>(</code><code>"queue %d id %d, message %s\n"</code><code>, i, qid[i], buf);</code>

<code>            </code><code>}</code>

<code>    </code><code>exit</code><code>(0);</code>

編譯指令:

<code>gcc pollmsg.c -o pollmsg -lapue -lpthread -std=c99</code>

2、使用UNIX與套接字輪詢XSI消息隊列(epoll版,改版)

<code>#include &lt;sys/epoll.h&gt;</code>

<code>#define FDSIZE     1000</code>

<code>#define EPOLLEVENTS    100</code>

<code>    </code><code>int</code> <code>epollfd;</code>

<code>    </code><code>struct</code> <code>epoll_event events[EPOLLEVENTS];</code>

<code>    </code><code>epollfd = epoll_create(FDSIZE);   </code><code>//建立epoll檔案描述符</code>

<code>        </code><code>struct</code> <code>epoll_event ev;</code>

<code>        </code><code>ev.events = EPOLLIN;</code>

<code>        </code><code>ev.data.fd = fd[0];</code>

<code>        </code><code>epoll_ctl(epollfd, EPOLL_CTL_ADD, fd[0], &amp;ev);   </code><code>//注冊fd[0]到epoll</code>

<code>        </code><code>}  </code>

<code>        </code><code>int</code> <code>occurred;</code>

<code>        </code><code>if</code> <code>((occurred = epoll_wait(epollfd, events, EPOLLEVENTS, -1)) &lt; 0) {    </code><code>//等待事件發生</code>

<code>            </code><code>err_sys(</code><code>"epoll error"</code><code>);</code>

<code>        </code><code>if</code> <code>(occurred == 0) {</code>

<code>            </code><code>err_sys(</code><code>"epoll timeout"</code><code>);</code>

<code>        </code><code>for</code> <code>(i = 0; i &lt; occurred; ++i) {</code>

<code>            </code><code>if</code> <code>(events[i].events &amp; EPOLLIN) {</code>

<code>                </code><code>if</code> <code>((n = read(events[i].data.fd, buf, </code><code>sizeof</code><code>(buf))) &lt; 0) {</code>

<code>                </code><code>printf</code><code>(</code><code>"main thread %u, message %s\n"</code><code>, (unsigned)pthread_self(), buf);</code>

<code>gcc epollmsg.c -o epollmsg -lapue -lpthread -std=c99</code>

3、給XSI消息隊列發送消息(測試程式,原版)

<code>#define MAXMSZ 512</code>

<code>int</code> <code>main(</code><code>int</code> <code>argc, </code><code>char</code> <code>*argv[])</code>

<code>    </code><code>key_t key;</code>

<code>    </code><code>long</code> <code>qid;</code>

<code>    </code><code>size_t</code> <code>nbytes;</code>

<code>    </code><code>if</code> <code>(argc != 3) {</code>

<code>        </code><code>fprintf</code><code>(stderr, </code><code>"usage: sendmsg KEY message\n"</code><code>);</code>

<code>        </code><code>exit</code><code>(1);</code>

<code>    </code><code>key = </code><code>strtol</code><code>(argv[1], NULL, 0);</code>

<code>    </code><code>//printf("key:0x%08X\n", (unsigned )key);</code>

<code>    </code><code>if</code> <code>((qid = msgget(key, 0)) &lt; 0) { </code><code>//打開一個現有隊列</code>

<code>        </code><code>err_sys(</code><code>"can't open queue key %s"</code><code>, argv[1]);</code>

<code>    </code><code>memset</code><code>(&amp;m, 0, </code><code>sizeof</code><code>(m));</code>

<code>    </code><code>strncpy</code><code>(m.mtext, argv[2], MAXMSZ - 1);</code>

<code>    </code><code>nbytes = </code><code>strlen</code><code>(m.mtext);</code>

<code>    </code><code>m.mtype = 1;</code>

<code>    </code><code>//printf("qid:%ld\n", qid);</code>

<code>    </code><code>if</code> <code>(msgsnd(qid, &amp;m, nbytes, 0) &lt; 0) { </code><code>//發送消息給指定消息隊列</code>

<code>        </code><code>err_sys(</code><code>"can't send message"</code><code>);</code>

<code>gcc sendmsg.c -o sendmsg -lapue -std=c99</code>

相關閱讀:

本文轉自walker snapshot部落格51CTO部落格,原文連結http://blog.51cto.com/walkerqt/1768445如需轉載請自行聯系原作者

RQSLT

繼續閱讀