自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

軟件開發(fā)實(shí)踐中的入隊(duì)列和出隊(duì)列操作的C代碼示例

開發(fā) 開發(fā)工具
大家都知道,隊(duì)列的特點(diǎn)是先入先出,即數(shù)據(jù)是按照入隊(duì)列的順序出隊(duì)列的。在實(shí)際的軟件開發(fā)項(xiàng)目中,當(dāng)一個(gè)中間模塊需要接收和發(fā)送大量的消息時(shí),隊(duì)列就可以大展身手了。

概述

[[178004]]

最近有在校的學(xué)生朋友在問我,數(shù)據(jù)結(jié)構(gòu)中的隊(duì)列在實(shí)際的軟件開發(fā)項(xiàng)目中有什么樣的用處。

大家都知道,隊(duì)列的特點(diǎn)是先入先出,即數(shù)據(jù)是按照入隊(duì)列的順序出隊(duì)列的。在實(shí)際的軟件開發(fā)項(xiàng)目中,當(dāng)一個(gè)中間模塊需要接收和發(fā)送大量的消息時(shí),隊(duì)列就可以大展身手了。我們可以將接收到的數(shù)據(jù)存儲(chǔ)在一個(gè)全局隊(duì)列中,然后在另外的程序流程中將數(shù)據(jù)從同一個(gè)全局隊(duì)列中取出來,經(jīng)過一定的處理之后將消息發(fā)送到另外的模塊。這樣做可以降低程序的性能瓶頸。

本文用實(shí)際的C代碼示例了簡(jiǎn)單的數(shù)據(jù)入隊(duì)列和出隊(duì)列的方法,大家可據(jù)此了解隊(duì)列的實(shí)際用法,也可參照來實(shí)現(xiàn)更加復(fù)雜的隊(duì)列操作。

C代碼

  1. /********************************************************************** 
  2. * 版權(quán)所有 (C)2016, Zhou Zhaoxiong 
  3. * 文件名稱:QueueUse.c 
  4. * 文件標(biāo)識(shí):無 
  5. * 內(nèi)容摘要:示例隊(duì)列的使用(入隊(duì)和出隊(duì)) 
  6. * 其它說明:無 
  7. * 當(dāng)前版本:V1.0 
  8. * 作    者:Zhou Zhaoxiong 
  9. * 完成日期:20160811 
  10. **********************************************************************/ 
  11. #include <stdio.h> 
  12. #include <string.h> 
  13. #include <ftw.h> 
  14. #include <pthread.h> 
  15. #include <time.h> 
  16.  
  17.  
  18. // 重定義數(shù)據(jù)類型 
  19. typedef signed   int        INT32; 
  20. typedef unsigned int        UINT32; 
  21. typedef unsigned char       UINT8; 
  22.  
  23. // 宏定義 
  24. #define     MAX_QUEUE      10000          // ***隊(duì)列元素個(gè)數(shù) 
  25.  
  26. // 結(jié)構(gòu)體變量 
  27. typedef struct 
  28.     UINT32 iID;             // 編號(hào) 
  29.     UINT8  szInfo[100];     // 描述 
  30. } T_StructInfo; 
  31.  
  32. // 全局變量定義 
  33. T_StructInfo g_tQueue[MAX_QUEUE] = {0};      // 隊(duì)列結(jié)構(gòu)體 
  34. UINT32 g_iQueueHead = 0;                     // 隊(duì)列頭部索引 
  35. UINT32 g_iQueueTail = 0;                     // 隊(duì)列尾部索引 
  36. pthread_mutex_t     g_mutex_queue_cs;        // 互斥信號(hào)量 
  37. pthread_cond_t      queue_cv; 
  38. pthread_mutexattr_t g_MutexAttr; 
  39.  
  40. // 函數(shù)聲明 
  41. void PutDataIntoQueue(void); 
  42. void GetDataFromQueue(void); 
  43. INT32 EnQueue(T_StructInfo tQueueData); 
  44. INT32 DeQueue(T_StructInfo *ptStructData); 
  45. void Sleep(UINT32 iCountMs); 
  46.  
  47.  
  48. /**************************************************************** 
  49. * 功能描述: 主函數(shù) 
  50. * 輸入?yún)?shù): 無 
  51. * 輸出參數(shù): 無 
  52. * 返 回 值: 0-執(zhí)行完成 
  53. * 其他說明: 無 
  54. * 修改日期       版本號(hào)        修改人        修改內(nèi)容 
  55. ------------------------------------------------------------- 
  56. * 20160811        V1.0     Zhou Zhaoxiong     創(chuàng)建 
  57. ****************************************************************/ 
  58. INT32 main(void) 
  59.     pthread_mutex_init(&g_mutex_queue_cs, &g_MutexAttr); 
  60.     pthread_cond_init(&queue_cv, NULL); 
  61.  
  62.  
  63.     // 在循環(huán)中執(zhí)行入隊(duì)和出隊(duì)操作 
  64.     while (1) 
  65.     { 
  66.         PutDataIntoQueue();  // 數(shù)據(jù)入隊(duì) 
  67.  
  68.  
  69.         Sleep(5 * 1000);     // 間隔5秒 
  70.  
  71.  
  72.         GetDataFromQueue();  // 數(shù)據(jù)出隊(duì) 
  73.  
  74.  
  75.         Sleep(60 * 1000);    // 每一分鐘執(zhí)行一次出隊(duì)和入隊(duì) 
  76.     } 
  77.  
  78.  
  79.     return 0; 
  80.  
  81.  
  82.  
  83.  
  84. /**************************************************************** 
  85. * 功能描述: 將數(shù)據(jù)加入隊(duì)列中 
  86. * 輸入?yún)?shù): 無 
  87. * 輸出參數(shù): 無 
  88. * 返 回 值: 0-成功   -1-失敗 
  89. * 其他說明: 無 
  90. * 修改日期       版本號(hào)        修改人        修改內(nèi)容 
  91. ------------------------------------------------------------- 
  92. * 20160811        V1.0     Zhou Zhaoxiong     創(chuàng)建 
  93. ****************************************************************/ 
  94. void PutDataIntoQueue(void) 
  95.     T_StructInfo tQueueData = {0}; 
  96.     static UINT32 iCountNum = 0; 
  97.  
  98.  
  99.     // 對(duì)結(jié)構(gòu)體的變量進(jìn)行賦值 
  100.     tQueueData.iID = iCountNum; 
  101.     snprintf(tQueueData.szInfo, sizeof(tQueueData.szInfo) - 1, "zhou%d", iCountNum); 
  102.  
  103.  
  104.     // 計(jì)數(shù)值累加 
  105.     iCountNum ++; 
  106.     if (iCountNum >= MAX_QUEUE-1) 
  107.     { 
  108.         iCountNum = 0; 
  109.     } 
  110.  
  111.  
  112.     // 將數(shù)據(jù)加入隊(duì)列(一直等到加入成功之后才退出) 
  113.     while (EnQueue(tQueueData) == -1) 
  114.     { 
  115.         Sleep(1000);       // 加入失敗,1秒后重試 
  116.     } 
  117.  
  118.  
  119.     // 打印加入的數(shù)據(jù) 
  120.     printf("PutDataIntoQueue: ID=%d, Info=%s\n", tQueueData.iID, tQueueData.szInfo); 
  121.  
  122.  
  123.  
  124.  
  125. /**************************************************************** 
  126. * 功能描述: 將數(shù)據(jù)取出隊(duì)列中 
  127. * 輸入?yún)?shù): 無 
  128. * 輸出參數(shù): 無 
  129. * 返 回 值: 0-成功   -1-失敗 
  130. * 其他說明: 無 
  131. * 修改日期       版本號(hào)        修改人        修改內(nèi)容 
  132. ------------------------------------------------------------- 
  133. * 20160811        V1.0     Zhou Zhaoxiong     創(chuàng)建 
  134. ****************************************************************/ 
  135. void GetDataFromQueue(void) 
  136.     T_StructInfo tQueueData = {0}; 
  137.  
  138.  
  139.     if (DeQueue(&tQueueData) == -1) 
  140.     { 
  141.         return
  142.     } 
  143.  
  144.  
  145.     // 打印取出的數(shù)據(jù) 
  146.     printf("GetDataFromQueue: ID=%d, Info=%s\n", tQueueData.iID, tQueueData.szInfo); 
  147.  
  148.  
  149.  
  150.  
  151. /**************************************************************** 
  152. * 功能描述: 數(shù)據(jù)入隊(duì)列 
  153. * 輸入?yún)?shù): tQueueData-隊(duì)列數(shù)據(jù) 
  154. * 輸出參數(shù): 無 
  155. * 返 回 值: 0-成功   -1-失敗 
  156. * 其他說明: 無 
  157. * 修改日期       版本號(hào)        修改人        修改內(nèi)容 
  158. ------------------------------------------------------------- 
  159. * 20160811        V1.0     Zhou Zhaoxiong     創(chuàng)建 
  160. ****************************************************************/ 
  161. INT32 EnQueue(T_StructInfo tQueueData) 
  162.     INT32  iRetVal  = 0; 
  163.     UINT32 iNextPos = 0; 
  164.  
  165.  
  166.     pthread_mutex_lock(&g_mutex_queue_cs); 
  167.     iNextPos = g_iQueueTail + 1; 
  168.  
  169.  
  170.     if (iNextPos >= MAX_QUEUE) 
  171.     { 
  172.         iNextPos = 0; 
  173.     } 
  174.  
  175.  
  176.     if (iNextPos == g_iQueueHead) 
  177.     { 
  178.         iRetVal = -1;   // 已達(dá)到隊(duì)列的***長(zhǎng)度 
  179.     } 
  180.     else 
  181.     { 
  182.         // 入隊(duì)列 
  183.         memset(&g_tQueue[g_iQueueTail], 0x00,  sizeof(T_StructInfo)); 
  184.         memcpy(&g_tQueue[g_iQueueTail], &tQueueData, sizeof(T_StructInfo)); 
  185.  
  186.  
  187.         g_iQueueTail = iNextPos; 
  188.     } 
  189.  
  190.  
  191.     pthread_cond_signal(&queue_cv); 
  192.     pthread_mutex_unlock(&g_mutex_queue_cs); 
  193.  
  194.  
  195.     return iRetVal; 
  196.  
  197.  
  198.  
  199.  
  200. /**************************************************************** 
  201. * 功能描述: 數(shù)據(jù)出隊(duì)列 
  202. * 輸入?yún)?shù): ptStructData-隊(duì)列數(shù)據(jù) 
  203. * 輸出參數(shù): 無 
  204. * 返 回 值: 0-成功   -1-失敗 
  205. * 其他說明: 無 
  206. * 修改日期       版本號(hào)        修改人        修改內(nèi)容 
  207. ------------------------------------------------------------- 
  208. * 20160811        V1.0     Zhou Zhaoxiong     創(chuàng)建 
  209. ****************************************************************/ 
  210. INT32 DeQueue(T_StructInfo *ptStructData) 
  211.     T_StructInfo tQueueData = {0}; 
  212.  
  213.  
  214.     if (ptStructData == NULL
  215.     { 
  216.         return -1; 
  217.     } 
  218.  
  219.  
  220.     pthread_mutex_lock(&g_mutex_queue_cs); 
  221.  
  222.  
  223.     while (g_iQueueHead == g_iQueueTail) 
  224.     { 
  225.         pthread_cond_wait(&queue_cv, &g_mutex_queue_cs); 
  226.     } 
  227.  
  228.  
  229.     memset(&tQueueData, 0x00, sizeof(T_StructInfo)); 
  230.     memcpy(&tQueueData, &g_tQueue[g_iQueueHead], sizeof(T_StructInfo)); 
  231.     g_iQueueHead ++; 
  232.  
  233.  
  234.     if (g_iQueueHead >= MAX_QUEUE) 
  235.     { 
  236.         g_iQueueHead = 0; 
  237.     } 
  238.  
  239.  
  240.     pthread_mutex_unlock(&g_mutex_queue_cs); 
  241.     memcpy(ptStructData, &tQueueData, sizeof(T_StructInfo)); 
  242.  
  243.  
  244.     return 0; 
  245.  
  246.  
  247.  
  248.  
  249. /********************************************************************** 
  250. * 功能描述: 程序休眠 
  251. * 輸入?yún)?shù): iCountMs-休眠時(shí)間(單位:ms) 
  252. * 輸出參數(shù): 無 
  253. * 返 回 值: 無 
  254. * 其它說明: 無 
  255. * 修改日期      版本號(hào)       修改人        修改內(nèi)容 
  256. ------------------------------------------------------------------ 
  257. * 20160811       V1.0     Zhou Zhaoxiong     創(chuàng)建 
  258. ********************************************************************/  
  259. void Sleep(UINT32 iCountMs) 
  260.     struct timeval t_timeout = {0}; 
  261.  
  262.  
  263.     if (iCountMs < 1000) 
  264.     { 
  265.         t_timeout.tv_sec  = 0; 
  266.         t_timeout.tv_usec = iCountMs * 1000; 
  267.     } 
  268.     else 
  269.     { 
  270.         t_timeout.tv_sec  = iCountMs / 1000; 
  271.         t_timeout.tv_usec = (iCountMs % 1000) * 1000; 
  272.     } 
  273.     select(0, NULLNULLNULL, &t_timeout);    // 調(diào)用select函數(shù)阻塞程序 

程序運(yùn)行情況

我們將上面編寫好的QueueUse.c文件上傳到Linux機(jī)器上,使用“gcc -g -o QueueUseQueueUse.c”命令編譯之后,生成QueueUse文件。之后,執(zhí)行“QueueUse”命令,即可看到程序的運(yùn)行結(jié)果(結(jié)果會(huì)不斷地更新)如下:

  1. ~/zhouzx/Test/QueueUse> QueueUse  
  2. PutDataIntoQueue: ID=0, Info=zhou0  
  3. GetDataFromQueue: ID=0, Info=zhou0  
  4. PutDataIntoQueue: ID=1, Info=zhou1  
  5. GetDataFromQueue: ID=1, Info=zhou1  
  6. PutDataIntoQueue: ID=2, Info=zhou2  
  7. GetDataFromQueue: ID=2, Info=zhou2  
  8. PutDataIntoQueue: ID=3, Info=zhou3  
  9. GetDataFromQueue: ID=3, Info=zhou3 

我們看到,數(shù)據(jù)先是被加入到隊(duì)列中,然后再?gòu)年?duì)列中取出來。

程序說明

***,在本程序中,入隊(duì)列和出隊(duì)列是在同一個(gè)函數(shù)中完成的,但是,在實(shí)際開發(fā)項(xiàng)目的程序中,入隊(duì)列和出隊(duì)列一般是在不同的程序流程(兩個(gè)不同的線程)中完成的。

第二,本程序的數(shù)據(jù)入隊(duì)列操作是在EnQueue函數(shù)中完成的,數(shù)據(jù)出隊(duì)列操作是在DeQueue函數(shù)中完成的,全局變量g_tQueue用于存放需要處理的數(shù)據(jù)。

第三,在實(shí)際開發(fā)項(xiàng)目的程序中,有可能會(huì)有很多流程都會(huì)調(diào)用入隊(duì)列和出隊(duì)列的函數(shù),為了防止多個(gè)流程同時(shí)向隊(duì)列中加入數(shù)據(jù)或取出數(shù)據(jù),在EnQueue和DeQueue函數(shù)中使用了鎖操作。也就是說,在操作數(shù)據(jù)之前,先用pthread_mutex_lock函數(shù)執(zhí)行加鎖操作,在處理完數(shù)據(jù)之后,再用pthread_mutex_unlock函數(shù)執(zhí)行解鎖操作。

第四,在實(shí)際開發(fā)項(xiàng)目中,為了防止程序從隊(duì)列中取數(shù)據(jù)的速率過快而使得下游模塊處理不過來,我們常在從隊(duì)列取出數(shù)據(jù)之后發(fā)消息的流程中控制數(shù)據(jù)的發(fā)送速率,具體每秒鐘發(fā)送多少條可在配置文件中設(shè)置。

【本文是51CTO專欄作者周兆熊的原創(chuàng)作品,轉(zhuǎn)載請(qǐng)通過51CTO獲取作者授權(quán)】

責(zé)任編輯:武曉燕 來源: csdn博客
相關(guān)推薦

2016-12-20 11:12:11

C代碼自測(cè)開發(fā)

2022-12-09 11:46:20

2023-06-09 19:01:03

軟件開發(fā)

2023-06-08 16:47:09

軟件開發(fā)工具

2022-08-04 10:32:04

Redis命令

2019-11-17 22:11:11

TCPSYN隊(duì)列Accept隊(duì)列

2021-04-23 09:00:00

開發(fā)安全編碼

2023-11-03 10:33:26

2009-07-17 17:29:13

多任務(wù)多線程

2011-12-15 01:01:48

ibmdw軟件開發(fā)

2023-02-09 16:48:12

軟件開發(fā)測(cè)試結(jié)對(duì)測(cè)試

2009-06-12 11:35:28

模式框架軟件設(shè)計(jì)

2023-08-24 09:44:16

數(shù)據(jù)庫(kù)性能

2022-10-12 14:17:39

物聯(lián)網(wǎng)軟件開發(fā)

2014-10-29 11:12:46

數(shù)據(jù)安全虹安

2023-12-07 12:59:46

C語(yǔ)言循環(huán)隊(duì)列代碼

2023-12-30 13:47:48

Redis消息隊(duì)列機(jī)制

2011-01-19 15:33:07

Qmail郵件隊(duì)列清除

2024-02-02 08:25:34

隊(duì)列與棧Python數(shù)據(jù)結(jié)構(gòu)

2011-08-29 11:25:29

清空service bSQL Server
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)