進程間通訊_消息隊列
定義: UNIX早起通信機制之一的信號能夠傳送的信息量有限,管道則只能傳送無格式的字節流,這無疑會給應用程序開發帶來不便。消息隊列(也稱報文隊列)則克服了這些缺點。
發展: 消息隊列就是一個消息的鏈表。可以把消息看做一個記錄,**具有特定的格式。進程可以向中按照一定的規則添加新消息;另一些進程則可以從消息隊列中讀取消息。
分類: 目前主要有兩種類型的消息隊列:POSIX消息隊列 以及系統V消息隊列,系統V消息隊列目前被大量使用。
持續性:系統V消息隊列是隨內核持續的,只有在內核重啓或者人工刪除時,該消息隊列纔會被刪除。
鍵值:消息隊列的內核持續性要求每個消息隊列都在系統範圍內對應唯一的鍵值,所以要獲得一個消息隊列的描述字,必須提供該消息的隊列鍵值。
#include<sys/types.h>
#include<sys/ipc.h>
key_t fork(char *pathname,char proj)
功能:返回文件名對應的鍵值。
pathname:文件名
proj:項目名(不爲0即可)
打開/創建
#include<sys/types.h>
#include<sys/ipc.h>
#include<sys/msg.h>
int msgget(key_t key,int msgflg)
key:鍵值,由ftok獲得。
msgflg:標誌位。
返回值:與鍵值key相對用的消息隊列描述字。
§ IPC_CREAT
創建新的消息隊列
§ IPC_EXCL
與IPC_CREAT一同使用,表示如果要創建的消息隊列已將存在,則返回錯誤。
§ IPC_NOWAIT
讀寫消息隊列要求無法得到滿足時,不阻塞。
在以下兩中情況下,將創建一個新的消息隊列:
*如果沒有與鍵值key相對應的消息隊列,並且msgflg中包含了IPC_CREAT標誌位。
*key參數爲IPC_PRIVATE.
創建消息隊列例子:
<code class="hljs perl has-numbering" style="display: block; padding: 0px; background-color: transparent; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-top-left-radius: 0px; border-top-right-radius: 0px; border-bottom-right-radius: 0px; border-bottom-left-radius: 0px; word-wrap: normal; background-position: initial initial; background-repeat: initial initial;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> open_queue(key_t keyval) { <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> qid; <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span>((qid=<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">msgget</span>(coeval,IPC_CREAT))==-<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>) { <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span>(-<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>); } <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span>(aid); }</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; background-color: rgb(238, 238, 238); top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right;"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li></ul>
發送消息
#include<sys/types.h>
#include<sys/ipc.h>
#include<sys/msg.h>
int magsed(int msqid,struct msgbuf*msgp,int msgsz,int msgflg)
功能:向消息隊列中發送一條消息。
消息格式
struct msgbuf
{
long mtype;//消息類型>0
char mtext[1];//消息數據的首地址
}
接收消息
#include<sys/types.h>
#include<sys/ipc.h>
#include<sys/msg.h>
int msgrcv(int msqid,struct msgbuf *msgp,int msgsz,long msgtyp,int msgflg)
功能:從msqid代表的消息隊列中讀取一個msgtyp類型的消息,並把消息存儲在msgp指向的msgbuf結構中。在成功的讀取了一條消息以後,隊列中這條消息將被刪除。
int read_message(int aid,long type,struct mymsgbuf*qbuf)
{
int result,length;
length=sizeof(struct mymsgbuf)-sizeof(long);
if((result=msgrcv(aid,qbuf,length,type,0))==-1)
return(-1);
return(resort);
}
程序1,向消息隊列寫信息,當接收到end試結束
<code class="hljs cpp has-numbering" style="display: block; padding: 0px; background-color: transparent; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-top-left-radius: 0px; border-top-right-radius: 0px; border-bottom-right-radius: 0px; border-bottom-left-radius: 0px; word-wrap: normal; background-position: initial initial; background-repeat: initial initial;"><span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">#include <stdlib.h></span> <span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">#include <stdio.h></span> <span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">#include <string.h></span> <span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">#include <errno.h></span> <span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">#include <unistd.h></span> <span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">#include <sys/types.h></span> <span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">#include <sys/ipc.h></span> <span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">#define MAX_TEXT 512</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">struct</span> my_msg_st { <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">long</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> my_msg_type; <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">char</span> some_text[MAX_TEXT]; }; <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">/* * 程序入口 * */</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> main(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span>) { <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> running=<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>; <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">struct</span> my_msg_st some_data; <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> msgid; <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">char</span> buffer[BUFSIZ]; <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">/*創建消息隊列*/</span> msgid=msgget((key_t)<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1234</span>,<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0666</span> | IPC_CREAT); <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span>(msgid==-<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>) { <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">fprintf</span>(stderr,<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"msgget failed with error:%d\n"</span>,errno); <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">exit</span>(EXIT_FAILURE); } <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">/*循環向消息隊列中添加消息*/</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">while</span>(running) { <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">printf</span>(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"Enter some text:"</span>); fgets(buffer,BUFSIZ,stdin); some_data.my_msg_type=<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>; <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">strcpy</span>(some_data.some_text,buffer); <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">/*添加消息*/</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span>(msgsnd(msgid,(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> *)&some_data,MAX_TEXT,<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>)==-<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>) { <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">fprintf</span>(stderr,<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"msgsed failed\n"</span>); <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">exit</span>(EXIT_FAILURE); } <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">/*用戶輸入的爲“end”時結束循環*/</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span>(<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">strncmp</span>(buffer,<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"end"</span>,<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">3</span>)==<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>) { running=<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>; } } <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">exit</span>(EXIT_SUCCESS); }</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; background-color: rgb(238, 238, 238); top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right;"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li><li style="box-sizing: border-box; padding: 0px 5px;">20</li><li style="box-sizing: border-box; padding: 0px 5px;">21</li><li style="box-sizing: border-box; padding: 0px 5px;">22</li><li style="box-sizing: border-box; padding: 0px 5px;">23</li><li style="box-sizing: border-box; padding: 0px 5px;">24</li><li style="box-sizing: border-box; padding: 0px 5px;">25</li><li style="box-sizing: border-box; padding: 0px 5px;">26</li><li style="box-sizing: border-box; padding: 0px 5px;">27</li><li style="box-sizing: border-box; padding: 0px 5px;">28</li><li style="box-sizing: border-box; padding: 0px 5px;">29</li><li style="box-sizing: border-box; padding: 0px 5px;">30</li><li style="box-sizing: border-box; padding: 0px 5px;">31</li><li style="box-sizing: border-box; padding: 0px 5px;">32</li><li style="box-sizing: border-box; padding: 0px 5px;">33</li><li style="box-sizing: border-box; padding: 0px 5px;">34</li><li style="box-sizing: border-box; padding: 0px 5px;">35</li><li style="box-sizing: border-box; padding: 0px 5px;">36</li><li style="box-sizing: border-box; padding: 0px 5px;">37</li><li style="box-sizing: border-box; padding: 0px 5px;">38</li><li style="box-sizing: border-box; padding: 0px 5px;">39</li><li style="box-sizing: border-box; padding: 0px 5px;">40</li><li style="box-sizing: border-box; padding: 0px 5px;">41</li><li style="box-sizing: border-box; padding: 0px 5px;">42</li><li style="box-sizing: border-box; padding: 0px 5px;">43</li><li style="box-sizing: border-box; padding: 0px 5px;">44</li><li style="box-sizing: border-box; padding: 0px 5px;">45</li><li style="box-sizing: border-box; padding: 0px 5px;">46</li><li style="box-sizing: border-box; padding: 0px 5px;">47</li><li style="box-sizing: border-box; padding: 0px 5px;">48</li><li style="box-sizing: border-box; padding: 0px 5px;">49</li><li style="box-sizing: border-box; padding: 0px 5px;">50</li><li style="box-sizing: border-box; padding: 0px 5px;">51</li><li style="box-sizing: border-box; padding: 0px 5px;">52</li><li style="box-sizing: border-box; padding: 0px 5px;">53</li><li style="box-sizing: border-box; padding: 0px 5px;">54</li><li style="box-sizing: border-box; padding: 0px 5px;">55</li><li style="box-sizing: border-box; padding: 0px 5px;">56</li><li style="box-sizing: border-box; padding: 0px 5px;">57</li></ul>
讀取消息隊列的數據,當爲end時結束
<code class="hljs cpp has-numbering" style="display: block; padding: 0px; background-color: transparent; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-top-left-radius: 0px; border-top-right-radius: 0px; border-bottom-right-radius: 0px; border-bottom-left-radius: 0px; word-wrap: normal; background-position: initial initial; background-repeat: initial initial;"><span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">#include <stdlib.h></span> <span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">#include <stdio.h></span> <span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">#include <string.h></span> <span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">#include <errno.h></span> <span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">#include <unistd.h></span> <span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">#include <sys/types.h></span> <span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">#include <sys/ipc.h></span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">struct</span> my_msg_st { <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">long</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> my_msg_type; <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">char</span> some_text[BUFSIZ]; }; <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">/* * 程序入口 * */</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> main(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span>) { <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> running=<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>; <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> msgid; <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">struct</span> my_msg_st some_data; <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">long</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> msg_to_receive=<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>; <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">/*創建消息隊列*/</span> msgid=msgget((key_t)<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1234</span>,<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0666</span> | IPC_CREAT); <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span>(msgid==-<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>) { <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">fprintf</span>(stderr,<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"msgget failed with error: %d\n"</span>,errno); <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">exit</span>(EXIT_FAILURE); } <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">/*循環從消息隊列中接收消息*/</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">while</span>(running) { <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">/*讀取消息*/</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span>(msgrcv(msgid,(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> *)&some_data,BUFSIZ,msg_to_receive,<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>)==-<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>) { <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">fprintf</span>(stderr,<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"msgrcv failed with error: %d\n"</span>,errno); <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">exit</span>(EXIT_FAILURE); } <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">printf</span>(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"You wrote: %s"</span>,some_data.some_text); <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">/*接收到的消息爲“end”時結束循環*/</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span>(<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">strncmp</span>(some_data.some_text,<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"end"</span>,<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">3</span>)==<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>) { running=<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>; } } <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">/*從系統內核中移走消息隊列*/</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span>(msgctl(msgid,IPC_RMID,<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>)==-<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>) { <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">fprintf</span>(stderr,<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"msgctl(IPC_RMID) failed\n"</span>); <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">exit</span>(EXIT_FAILURE); } <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">exit</span>(EXIT_SUCCESS); } </code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; background-color: rgb(238, 238, 238); top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right;"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li><li style="box-sizing: border-box; padding: 0px 5px;">20</li><li style="box-sizing: border-box; padding: 0px 5px;">21</li><li style="box-sizing: border-box; padding: 0px 5px;">22</li><li style="box-sizing: border-box; padding: 0px 5px;">23</li><li style="box-sizing: border-box; padding: 0px 5px;">24</li><li style="box-sizing: border-box; padding: 0px 5px;">25</li><li style="box-sizing: border-box; padding: 0px 5px;">26</li><li style="box-sizing: border-box; padding: 0px 5px;">27</li><li style="box-sizing: border-box; padding: 0px 5px;">28</li><li style="box-sizing: border-box; padding: 0px 5px;">29</li><li style="box-sizing: border-box; padding: 0px 5px;">30</li><li style="box-sizing: border-box; padding: 0px 5px;">31</li><li style="box-sizing: border-box; padding: 0px 5px;">32</li><li style="box-sizing: border-box; padding: 0px 5px;">33</li><li style="box-sizing: border-box; padding: 0px 5px;">34</li><li style="box-sizing: border-box; padding: 0px 5px;">35</li><li style="box-sizing: border-box; padding: 0px 5px;">36</li><li style="box-sizing: border-box; padding: 0px 5px;">37</li><li style="box-sizing: border-box; padding: 0px 5px;">38</li><li style="box-sizing: border-box; padding: 0px 5px;">39</li><li style="box-sizing: border-box; padding: 0px 5px;">40</li><li style="box-sizing: border-box; padding: 0px 5px;">41</li><li style="box-sizing: border-box; padding: 0px 5px;">42</li><li style="box-sizing: border-box; padding: 0px 5px;">43</li><li style="box-sizing: border-box; padding: 0px 5px;">44</li><li style="box-sizing: border-box; padding: 0px 5px;">45</li><li style="box-sizing: border-box; padding: 0px 5px;">46</li><li style="box-sizing: border-box; padding: 0px 5px;">47</li><li style="box-sizing: border-box; padding: 0px 5px;">48</li><li style="box-sizing: border-box; padding: 0px 5px;">49</li><li style="box-sizing: border-box; padding: 0px 5px;">50</li><li style="box-sizing: border-box; padding: 0px 5px;">51</li><li style="box-sizing: border-box; padding: 0px 5px;">52</li><li style="box-sizing: border-box; padding: 0px 5px;">53</li><li style="box-sizing: border-box; padding: 0px 5px;">54</li><li style="box-sizing: border-box; padding: 0px 5px;">55</li><li style="box-sizing: border-box; padding: 0px 5px;">56</li><li style="box-sizing: border-box; padding: 0px 5px;">57</li><li style="box-sizing: border-box; padding: 0px 5px;">58</li><li style="box-sizing: border-box; padding: 0px 5px;">59</li><li style="box-sizing: border-box; padding: 0px 5px;">60</li></ul>