<sub id="1djzl"><dfn id="1djzl"><ins id="1djzl"></ins></dfn></sub>

    <sub id="1djzl"><delect id="1djzl"></delect></sub>

    <address id="1djzl"></address>
    <address id="1djzl"><dfn id="1djzl"></dfn></address><address id="1djzl"></address><form id="1djzl"></form>

    <address id="1djzl"><dfn id="1djzl"></dfn></address>
    <address id="1djzl"><listing id="1djzl"></listing></address>
    <thead id="1djzl"><var id="1djzl"><mark id="1djzl"></mark></var></thead>

        <form id="1djzl"><listing id="1djzl"></listing></form>
        <address id="1djzl"><var id="1djzl"><output id="1djzl"></output></var></address>

          <sub id="1djzl"></sub>

            <address id="1djzl"><var id="1djzl"></var></address>

              <sub id="1djzl"><dfn id="1djzl"></dfn></sub><sub id="1djzl"><var id="1djzl"><ins id="1djzl"></ins></var></sub>

                  <sub id="1djzl"><var id="1djzl"><output id="1djzl"></output></var></sub>

                    循環隊列及C語言實現<三>

                    首頁    學習交流    C語言    循環隊列及C語言實現<三>

                    在之前的博客中給出了設計循環隊列的思路以及源碼,這些可都是經過我長期大數據測試的驗證哦。當然,現在的很多開源項目和一些封裝好的類或接口也都有類似的隊列實現方法,之所以我還在使用自己寫的這一套方法,主要是因為靈活性較大,我可以定制出適合自己的接口。而且在其上的操作邏輯和結果我也心知肚明。
                    好了,之所以隔了這么久寫這個第三篇文章,主要是考慮到以下因素:
                    <1> 隊列并發操作的同步問題;(安全性)
                    <2> 部分情況下,希望在讀取隊列后進行隊列回寫操作。(比如進行數據分析按一幀一幀進行解析的時候,發現隊列里緩存數據不足一幀,此時就需要回寫,等再有數據保存到隊列)

                    下面先提出 <1> 的解決方法,使用互斥鎖和信號量,給出簡單例子:

                    Exp1:

                    pthread_mutex_init(&mutex);
                    
                    thread1:
                        ...
                        pthread_mutex_lock(&mutex);
                        WriteQueue(q, wbuf, writelen);
                        pthread_mutex_unlock(&mutex);
                        ...
                    
                    thread2:
                        ...
                        pthread_mutex_lock(&mutex);
                        ReadQueue(q, rbuf, &readlen);
                        pthread_mutex_unlock(&mutex);
                        ...

                    Exp2:

                    sem_init(&sem);
                    
                    thread1:
                        ...
                        sem_wait(&sem);
                        WriteQueue(q, wbuf, writelen);
                        sem_post(&sem);
                        ...
                    
                    thread2:
                        ...
                        sem_wait(&sem);
                        ReadQueue(q, rbuf, &readlen);
                        sem_post(&sem);
                        ...

                    其他的方式還有很多啦,就不一一列舉了,小型項目開發應該是足夠了。

                    至于方案 <2> 的解決方法,在 queue.c 中添加一個回寫函數就好啦,原理也很簡單,把讀指針移動到之前的位置就可以啦。需要考慮的就是回寫的長度大于隊列當前讀指針距離隊列頭的位置時的處理,詳細可以參見我下面的代碼:

                    unsigned int RecoverReadQueue(Queue *q, unsigned int len)
                    {
                        unsigned int ret = 0;
                        unsigned int rest = q->read;
                    
                        if (rest >= len)
                        {
                            q->read -= len;
                        }
                        else
                        {
                            q->read = q->size - (len - rest);
                        }
                        q->space -= len;
                    
                        return ret;
                    }

                    為了防止部分讀者忽略了之前文章,我還是把最新的源碼貼出來以供參考:

                    queue.h

                    Exp1:
                    pthread_mutex_init(&mutex);
                    
                    thread1:    ...
                        pthread_mutex_lock(&mutex);
                        WriteQueue(q, wbuf, writelen);
                        pthread_mutex_unlock(&mutex);    ...thread2:    ...
                        pthread_mutex_lock(&mutex);
                        ReadQueue(q, rbuf, &readlen);
                        pthread_mutex_unlock(&mutex);    ...123456789101112131415
                    Exp2:
                    sem_init(&sem);
                    
                    thread1:    ...
                        sem_wait(&sem);
                        WriteQueue(q, wbuf, writelen);
                        sem_post(&sem);    ...thread2:    ...
                        sem_wait(&sem);
                        ReadQueue(q, rbuf, &readlen);
                        sem_post(&sem);    ...123456789101112131415
                    其他的方式還有很多啦,就不一一列舉了,小型項目開發應該是足夠了。
                    至于方案 <2> 的解決方法,在 queue.c 中添加一個回寫函數就好啦,原理也很簡單,把讀指針移動到之前的位置就可以啦。需要考慮的就是回寫的長度大于隊列當前讀指針距離隊列頭的位置時的處理,詳細可以參見我下面的代碼:
                    unsigned int RecoverReadQueue(Queue *q, unsigned int len)
                    {
                        unsigned int ret = 0;
                        unsigned int rest = q->read;    if (rest >= len)
                        {
                            q->read -= len;
                        }    else
                        {
                            q->read = q->size - (len - rest);
                        }
                        q->space -= len;
                    
                        return ret;
                    }1234567891011121314151617
                    為了防止部分讀者忽略了之前文章,我還是把最新的源碼貼出來以供參考:
                    queue.h
                    #ifndef _QUEUE_H
                    #define _QUEUE_H
                    #include <stdio.h>
                    #include <stdlib.h>
                    #include <string.h>
                    #include <stdbool.h>
                    
                    /**
                     * Queue - queue structure
                     * @buf: queue buffer
                     * @read: position of read
                     * @write: position of write
                     * @size: buffer size
                     * @space: writable buffer size
                     */
                    typedef struct {
                        unsigned char *buf;
                        unsigned int read;
                        unsigned int write;
                        unsigned int size;
                        unsigned int space;
                        bool OverFlow;
                    } Queue;
                    
                    #define Avail(q) (q->size - q->space)
                    
                    
                    extern bool Queue_Empty(Queue *q);
                    extern bool Queue_Full(Queue *q);
                    extern unsigned int RecoverReadQueue(Queue *q, unsigned int len);
                    extern void Queue_Init(Queue *q, int size);
                    extern void Queue_Destroy(Queue *q);
                    extern bool AddQueue(Queue *q, unsigned char val);
                    extern bool DelQueue(Queue *q, unsigned char *val);
                    extern unsigned int WriteQueue(Queue *q, unsigned char *buf, unsigned int len);
                    extern unsigned int ReadQueue(Queue *q, unsigned char *buf, unsigned int len);
                    
                    #endif

                    queue.c

                    /*
                     * Queue operation API - 1.1
                     *
                     * Copyright (C) 2016 SoldierJazz (SoldierJazz@163.com)
                     *
                     * This program is free software; you can redistribute it and/or
                     * modify it. 
                     *
                     */
                    
                    #include "queue.h"
                    
                    /**
                     * Queue_Init - init a queue
                     * @q: pointer of queue
                     * @size: size of buffer in queue
                     *
                     * Must be called when started. 
                     */
                    void Queue_Init(Queue *q, int size)
                    {
                        q->buf = (unsigned char *)malloc(sizeof(unsigned char) * size);
                        memset(q->buf, 0x00, size);
                        q->read = 0;
                        q->write = 0;
                        q->size = size;
                        q->space = size;
                        q->OverFlow = false;
                    }
                    
                    /**
                     * Queue_Destroy - destroy a queue
                     * @q: pointer of queue
                     */
                    void Queue_Destroy(Queue *q)
                    {
                        free(q->buf);
                    }
                    
                    /**
                     * Queue_Empty - tests whether a queue is empty
                     * @q: the queue to test
                     */
                    bool Queue_Empty(Queue *q) 
                    {
                        return (q->space == q->size);
                    }
                    
                    /**
                     * Queue_Full - tests whether a queue is full
                     * @q: the queue to test
                     */
                    bool Queue_Full(Queue *q)
                    {
                        return (q->space == 0);
                    }
                    
                    /**
                     * AddQueue - add a byte to queue
                     * @q: the queue to add to
                     * @val: the char to add
                     */
                    bool
                    bool AddQueue(Queue *q, unsigned char val)
                    {
                        if (!Queue_Full(q)) {
                            q->buf[q->write] = val;
                            q->write = (q->write + 1) % q->size;
                            q->space--;
                            return true;
                        } 
                        return false;
                    }
                    
                    /**
                     * DelQueue - delete a byte from queue
                     * @q: the queue to delete from
                     * @val: the char deleted
                     */
                    bool DelQueue(Queue *q, unsigned char *val)
                    {
                        if (!Queue_Empty(q)) {
                            *val = q->buf[q->read];
                            q->read = (q->read + 1) % q->size;
                            q->space++;
                            return true;
                        }
                        return false;
                    }
                    
                    /**
                     * WriteQueue - write buffers to queue
                     * @q: the queue to write in
                     * @buf: pointer of write buffer
                     * @len: length of write buffer
                     */
                    unsigned int WriteQueue(Queue *q, unsigned char *buf, unsigned int len)
                    {
                        unsigned int ret = 0;
                        unsigned int rest = q->size - q->write;
                    
                        if (!Queue_Full(q)) {
                            if (q->space >= len) {
                                ret = len;
                                if (rest >= len) {
                                    memcpy(q->buf + q->write, buf, len);
                                    q->write = (q->write + len) % q->size;
                                    q->space -= len;
                                } else {
                                    memcpy(q->buf + q->write, buf, rest);
                                    q->write = 0;
                                    memcpy(q->buf, buf + rest, len - rest);
                                    q->write = len -rest;
                                    q->space -= len;
                                }
                            } else {
                                ret = q->space;
                                if (rest >= q->space) {
                                    memcpy(q->buf + q->write, buf, q->space);
                                    q->write = (q->write + q->space) % q->size;
                                    q->space = 0;
                                } else {
                                    memcpy(q->buf + q->write, buf, rest);
                                    q->write = 0;
                                    memcpy(q->buf, buf + rest, q->space - rest);
                                    q->write = q->space -rest;
                                    q->space = 0;
                                }
                            }   
                        } 
                        return ret;
                    }
                    
                    /**
                     * RecoverReadQueue - recover len of buffer from queue
                     * @q: the queue to recover from
                     * @len: recover length
                     */
                    unsigned int RecoverReadQueue(Queue *q, unsigned int len)
                    {
                        unsigned int ret = 0;
                        unsigned int rest = q->read;
                    
                        if (rest >= len)
                        {
                            q->read -= len;
                        }
                        else
                        {
                            q->read = q->size - (len - rest);
                        }
                        q->space -= len;
                    
                        return ret;
                    }
                    
                    /**
                     * ReadQueue - read buffers from queue
                     * @q: the queue to read from
                     * @buf: pointer of read buffer
                     * @len: read length
                     */
                    unsigned int ReadQueue(Queue *q, unsigned char *buf, unsigned int len)
                    {
                        unsigned int rest = q->size - q->read;
                        unsigned int ret = 0;
                    
                        if (!Queue_Empty(q)) {
                            if (Avail(q) >= len) {
                                ret = len;
                                if (rest >= len) {
                                    memcpy(buf, q->buf + q->read, len);
                                    q->read = (q->read + len) % q->size;
                                    q->space += len;
                                } else {
                                    memcpy(buf, q->buf + q->read, rest);
                                    q->read = 0;
                                    memcpy(buf + rest, q->buf, len - rest);
                                    q->read = len -rest;
                                    q->space += len;
                                }
                                return len;
                            } else {
                                ret = Avail(q);
                                if (rest >= Avail(q)) {
                                    memcpy(buf, q->buf + q->read, Avail(q));
                                    q->read = (q->read + Avail(q)) % q->size;
                                    q->space = q->size;
                                } else {
                                    memcpy(buf, q->buf + q->read, rest);
                                    q->read = 0;
                                    memcpy(buf + rest, q->buf, Avail(q) - rest);
                                    q->read = Avail(q) -rest;
                                    q->space = q->size;
                                }
                            }
                        } 
                        return ret;
                    }
                    
                    轉載自:https://blog.csdn.net/JAZZSOLDIER/article/details/53913136	


                    2018年8月17日 22:29
                    ?瀏覽量:0
                    ?收藏
                    国产偷拍欧洲日韩亚洲 - 视频 - 在线观看 - 影视资讯 - 新赏网