wangzhengquan
2020-07-08 7d3086a481899b03c230eb06a29aa57677041725
update
1个文件已添加
18个文件已修改
514 ■■■■■ 已修改文件
squeue/include/array_lock_free_queue.h 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
squeue/include/linked_lock_free_queue.h 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
squeue/include/lock_free_queue.h 23 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
squeue/include/queue_factory.h 111 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
squeue/include/shm_queue.h 184 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
test/Makefile 51 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
test/multiple_queue_consumer 补丁 | 查看 | 原始文档 | blame | 历史
test/multiple_queue_consumer.c 14 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
test/multiple_queue_productor 补丁 | 查看 | 原始文档 | blame | 历史
test/multiple_queue_productor.c 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
test/single_consumer 补丁 | 查看 | 原始文档 | blame | 历史
test/single_consumer.c 23 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
test/single_productor 补丁 | 查看 | 原始文档 | blame | 历史
test/single_productor.c 24 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
test/test.h 8 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
test/test_queue 补丁 | 查看 | 原始文档 | blame | 历史
test/test_queue.c 18 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
test/test_timeout 补丁 | 查看 | 原始文档 | blame | 历史
test/test_timeout.c 24 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
squeue/include/array_lock_free_queue.h
@@ -39,6 +39,8 @@
    /// @brief calculate the index in the circular array that corresponds
    /// to a particular "count" value
    inline uint32_t countToIndex(uint32_t a_count);
    ELEM_T& operator[](unsigned i);
    
private:    
    size_t Q_SIZE;
@@ -304,4 +306,18 @@
    return false;    
}
template <typename ELEM_T>
ELEM_T& ArrayLockFreeQueue<ELEM_T>::operator[](unsigned int i)
{
    int currentCount = m_count.load();
    uint32_t currentReadIndex = m_readIndex.load();
    if (i < 0 || i >= currentCount)
    {
        std::cerr << "Error in array limits: " << i << " is out of range\n";
        std::exit(EXIT_FAILURE);
    }
    return m_theQueue[countToIndex(currentReadIndex+i)];
}
#endif // __LOCK_FREE_QUEUE_IMPL_MULTIPLE_PRODUCER_H__
squeue/include/linked_lock_free_queue.h
@@ -68,7 +68,7 @@
    // preemptive definitions to prevent public copying
    LinkedLockFreeQueue(const LinkedLockFreeQueue & q) : qsize(0) { }
    LinkedLockFreeQueue & operator=(const LinkedLockFreeQueue & q) { return *this;}
public:
protected:
    LinkedLockFreeQueue(size_t qs = Q_SIZE); // create queue with a qs limit
    ~LinkedLockFreeQueue();
    bool empty() const;
squeue/include/lock_free_queue.h
@@ -1,8 +1,6 @@
#ifndef __LOCK_FREE_QUEUE_H__
#define __LOCK_FREE_QUEUE_H__
#include <stdint.h>     // uint32_t
#include <atomic>
#include <usg_common.h>
#include <assert.h> // assert()
#include "mm.h" 
@@ -72,18 +70,23 @@
class LockFreeQueue
{
    template < typename ELEM_T_ >
    friend class SHMQueue;
private:
    int slots;
    int items;
public:
    std::atomic_uint reference;
    /// @brief constructor of the class
    LockFreeQueue(size_t qsize = LOCK_FREE_Q_DEFAULT_SIZE);
protected:
     LockFreeQueue(size_t qsize = LOCK_FREE_Q_DEFAULT_SIZE);
    
    /// @brief destructor of the class. 
    /// Note it is not virtual since it is not expected to inherit from this
    /// template
    ~LockFreeQueue();
public:
    std::atomic_uint reference;
    /// @brief constructor of the class
    /// @brief returns the current number of items in the queue
    /// It tries to take a snapshot of the size of the queue, but in busy environments
@@ -102,6 +105,8 @@
    inline bool full();
    inline bool empty();
    inline ELEM_T& operator[](unsigned i);
    /// @brief push an element at the tail of the queue
    /// @param the element to insert in the queue
@@ -300,6 +305,12 @@
    
}
template <
    typename ELEM_T,
    template <typename T> class Q_TYPE>
ELEM_T& LockFreeQueue<ELEM_T, Q_TYPE>::operator[](unsigned i) {
    return m_qImpl.operator[](i);
}
template <
    typename ELEM_T, 
squeue/include/queue_factory.h
@@ -1,70 +1,71 @@
#ifndef QFACTORY_H
#define QFACTORY_H
#include "usg_common.h"
#include "mm.h"
#include "hashtable.h"
#include "lock_free_queue.h"
// #ifndef QFACTORY_H
// #define QFACTORY_H
// #include "usg_common.h"
// #include "mm.h"
// #include "hashtable.h"
// #include "lock_free_queue.h"
class QueueFactory{
private:
// class QueueFactory{
// private:
    static hashtable_t * getHashTable() {
        static hashtable_t *hashtable = NULL;
        int first;
//     static hashtable_t * getHashTable() {
//         static hashtable_t *hashtable = NULL;
//         int first;
          
        if(hashtable == NULL) {
            first = mm_init(sizeof(hashtable_t), (void **)&hashtable);
            if (first)
               hashtable_init(hashtable);
        }
        return hashtable;
//         if(hashtable == NULL) {
//             first = mm_init(sizeof(hashtable_t), (void **)&hashtable);
//             if (first)
//                hashtable_init(hashtable);
//         }
//         return hashtable;
        
    }
//     }
    template <typename T> static
    LockFreeQueue<T>* _createQueue(int key, size_t size = 16) {
        LockFreeQueue<T> *queue;
        hashtable_t *hashtable = getHashTable();
        //LockFreeQueue<int, 10000> q;
        if ((queue = (LockFreeQueue<T> *)hashtable_get(hashtable, key)) == NULL ) {
            queue = new LockFreeQueue<T>(size);
            hashtable_put(hashtable,  key, (void *)queue);
        }
//     template <typename T> static
//     LockFreeQueue<T>* _createQueue(int key, size_t size = 16) {
//         LockFreeQueue<T> *queue;
//         hashtable_t *hashtable = getHashTable();
//         //LockFreeQueue<int, 10000> q;
//         if ((queue = (LockFreeQueue<T> *)hashtable_get(hashtable, key)) == NULL ) {
//             queue = new LockFreeQueue<T>(size);
//             hashtable_put(hashtable,  key, (void *)queue);
//         }
        
        return queue;
    }
//         return queue;
//     }
     
public:
// public:
    template <typename T> static
    LockFreeQueue<T>* createQueue(int key, size_t size = 16) {
        LockFreeQueue<T> *queue = _createQueue<T>(key, size);
        queue->reference++;
        LoggerFactory::getLogger().debug("createQueue reference===%d", queue->reference.load());
        return queue;
    }
//     template <typename T> static
//     LockFreeQueue<T>* createQueue(int key, size_t size = 16) {
//         LockFreeQueue<T> *queue = _createQueue<T>(key, size);
//         queue->reference++;
//         LoggerFactory::getLogger().debug("createQueue reference===%d", queue->reference.load());
//         return queue;
//     }
    /**
     * destroy queue
    */
    template <typename T> static
    void dropQueue(int key) {
        LockFreeQueue<T> *queue = _createQueue<T> (key);
        if(queue == NULL)
            return;
//     /**
//      * destroy queue
//     */
//     template <typename T> static
//     void dropQueue(int key) {
//         LockFreeQueue<T> *queue = _createQueue<T> (key);
//         if(queue == NULL)
//             return;
        queue->reference--;
        LoggerFactory::getLogger().debug("dropQueue reference===%d", queue->reference.load());
        if(queue->reference == 0) {
            delete queue;
            hashtable_t *hashtable = getHashTable();
            hashtable_remove(hashtable, key);
        }
//         queue->reference--;
//         LoggerFactory::getLogger().debug("dropQueue reference===%d", queue->reference.load());
//         if(queue->reference == 0) {
//             delete queue;
//             hashtable_t *hashtable = getHashTable();
//             hashtable_remove(hashtable, key);
//         }
        
    }
//     }
};
#endif
// };
// #endif
squeue/include/shm_queue.h
New file
@@ -0,0 +1,184 @@
#ifndef __SHM_QUEUE_H__
#define __SHM_QUEUE_H__
#include <usg_common.h>
#include "mm.h"
#include "hashtable.h"
#include "lock_free_queue.h"
#include "logger_factory.h"
// default Queue size
// #define LOCK_FREE_Q_DEFAULT_SIZE 16
//
template < typename ELEM_T>
class SHMQueue
{
private:
    static hashtable_t * getHashTable() {
        static hashtable_t *hashtable = NULL;
        if(hashtable == NULL) {
            int first = mm_init(sizeof(hashtable_t), (void **)&hashtable);
            if (first)
               hashtable_init(hashtable);
        }
        return hashtable;
    }
private:
    const int KEY;
public:
    /// @brief constructor of the class
    SHMQueue(int key=0, size_t qsize = LOCK_FREE_Q_DEFAULT_SIZE);
    /// @brief destructor of the class.
    /// Note it is not virtual since it is not expected to inherit from this
    /// template
    ~SHMQueue();
    /// @brief returns the current number of items in the queue
    /// It tries to take a snapshot of the size of the queue, but in busy environments
    /// this function might return bogus values.
    ///
    /// If a reliable queue size must be kept you might want to have a look at
    /// the preprocessor variable in this header file called '_WITH_LOCK_FREE_Q_KEEP_REAL_SIZE'
    /// it enables a reliable size though it hits overall performance of the queue
    /// (when the reliable size variable is on it's got an impact of about 20% in time)
    inline uint32_t size();
    /// @brief return true if the queue is full. False otherwise
    /// It tries to take a snapshot of the size of the queue, but in busy
    /// environments this function might return bogus values. See help in method
    /// SHMQueue::size
    inline bool full();
    inline bool empty();
    inline bool push(const ELEM_T &a_data);
    inline bool push_nowait(const ELEM_T &a_data);
    inline bool push_timeout(const ELEM_T &a_data, struct timespec * timeout);
    inline bool pop(ELEM_T &a_data);
    inline bool pop_nowait(ELEM_T &a_data);
    inline bool pop_timeout(ELEM_T &a_data, struct timespec * timeout);
    inline ELEM_T& operator[](unsigned i);
protected:
    /// @brief the actual queue-> methods are forwarded into the real
    ///        implementation
    LockFreeQueue<ELEM_T>* queue;
private:
    /// @brief disable copy constructor declaring it private
    SHMQueue<ELEM_T>(const SHMQueue<ELEM_T> &a_src);
};
template < typename ELEM_T >
SHMQueue<ELEM_T>::SHMQueue(int key, size_t qsize): KEY(key)
{
    hashtable_t *hashtable = getHashTable();
    //LockFreeQueue<int, 10000> q;
    if ((queue = (LockFreeQueue<ELEM_T> *)hashtable_get(hashtable, key)) == NULL ) {
        queue = new LockFreeQueue<ELEM_T>(qsize);
        hashtable_put(hashtable,  key, (void *)queue);
    }
    queue->reference++;
    LoggerFactory::getLogger().debug("SHMQueue constructor reference===%d", queue->reference.load());
}
template < typename ELEM_T >
SHMQueue<ELEM_T>::~SHMQueue()
{
    queue->reference--;
    LoggerFactory::getLogger().debug("SHMQueue destructor  reference===%d", queue->reference.load());
    if(queue->reference == 0) {
        delete queue;
        hashtable_t *hashtable = getHashTable();
        hashtable_remove(hashtable, KEY);
    }
}
template < typename ELEM_T >
inline uint32_t SHMQueue<ELEM_T>::size()
{
    return queue->size();
}
template < typename ELEM_T >
inline bool SHMQueue<ELEM_T>::full()
{
    return queue->full();
}
template < typename ELEM_T >
inline bool SHMQueue<ELEM_T>::empty()
{
    return queue->empty();
}
template < typename ELEM_T >
inline bool SHMQueue<ELEM_T>::push(const ELEM_T &a_data)
{
   return queue->push(a_data);
}
template <
    typename ELEM_T >
inline bool SHMQueue<ELEM_T>::push_nowait(const ELEM_T &a_data)
{
   return queue->push_nowait(a_data);
}
template < typename ELEM_T >
inline bool SHMQueue<ELEM_T>::push_timeout(const ELEM_T &a_data, struct timespec * timeout)
{
    return queue->push_timeout(a_data, timeout);
}
template < typename ELEM_T >
inline bool SHMQueue<ELEM_T>::pop(ELEM_T &a_data)
{
   return queue->pop(a_data);
}
template < typename ELEM_T >
inline bool SHMQueue<ELEM_T>::pop_nowait(ELEM_T &a_data)
{
    return queue->pop_nowait(a_data);
}
template < typename ELEM_T >
inline bool SHMQueue<ELEM_T>::pop_timeout(ELEM_T &a_data, struct timespec * timeout)
{
   return queue->pop_timeout(a_data, timeout);
}
template < typename ELEM_T >
inline ELEM_T& SHMQueue<ELEM_T>::operator[](unsigned i) {
     return queue->operator[](i);
}
#endif // _LOCK_FREE_QUEUE_H__
test/Makefile
@@ -1,52 +1,3 @@
# ROOT=..
# EXTRALIBS+=
# INCLUDE+=-I. -I$(ROOT)/squeue/include -I$(ROOT)/squeue -I$(ROOT)/common/include
# LIBCOMMON=$(ROOT)/common/libusgcommon.a
# LIBSQUEUE=$(ROOT)/squeue/libsqueue.a
# LDLIBS = -lpthread
# PLATFORM=$(shell $(ROOT)/systype.sh)
# include $(ROOT)/Make.defines.$(PLATFORM)
# PROGS =    test_queue productor consumer single_productor single_consumer
# all: $(PROGS)
# # test1: $(LIBCOMMON)
# # 如果包A 引用包B, B 要放在 A 后面
# # svshm_reader:  binary_sems.c  $(LIBSQUEUE) $(LIBCOMMON)
# # svshm_writer:  binary_sems.c  $(LIBSQUEUE) $(LIBCOMMON)
# test_queue: test.h  $(ROOT)/squeue/include/SArrayLockFreeQueue.h $(ROOT)/squeue/include/SLinkedLockFreeQueue.h  $(ROOT)/squeue/include/QFactory.h  $(LIBSQUEUE) $(LIBCOMMON)
# productor: test.h  $(ROOT)/squeue/include/SArrayLockFreeQueue.h $(ROOT)/squeue/include/SLinkedLockFreeQueue.h $(ROOT)/squeue/include/QFactory.h  $(LIBSQUEUE) $(LIBCOMMON)
# consumer: test.h  $(ROOT)/squeue/include/SArrayLockFreeQueue.h $(ROOT)/squeue/include/SLinkedLockFreeQueue.h $(ROOT)/squeue/include/QFactory.h $(LIBSQUEUE) $(LIBCOMMON)
# single_productor: test.h  $(ROOT)/squeue/include/SArrayLockFreeQueue.h $(ROOT)/squeue/include/SLinkedLockFreeQueue.h $(ROOT)/squeue/include/QFactory.h  $(LIBSQUEUE) $(LIBCOMMON)
# single_consumer: test.h  $(ROOT)/squeue/include/SArrayLockFreeQueue.h $(ROOT)/squeue/include/SLinkedLockFreeQueue.h $(ROOT)/squeue/include/QFactory.h $(LIBSQUEUE) $(LIBCOMMON)
# # test_lostdata: test.h  $(LIBSQUEUE) $(LIBCOMMON)
# # consumer_timeout: $(ROOT)/squeue/include/squeue.h test.h  $(LIBSQUEUE) $(LIBCOMMON)
# # productor_timeout: $(ROOT)/squeue/squeue.h $(LIBSQUEUE) $(LIBCOMMON)
# # test_atomic: $(ROOT)/squeue/squeue.h $(LIBSQUEUE) $(LIBCOMMON)
# clean:
#     rm -f $(PROGS) $(TEMPFILES) *.o
#
# Makefile for common library.
#
@@ -67,8 +18,6 @@
build: $(PROGS)
# test1: $(LIBCOMMON)
test/multiple_queue_consumer
Binary files differ
test/multiple_queue_consumer.c
@@ -5,11 +5,9 @@
#define NTHREADS 4 
struct Targ targs[NTHREADS];
size_t qsize = 16;
bool stop = false;
void sigint_handler(int sig) {
  mm_destroy();
  exit(0);
  stop = true;
}
@@ -17,18 +15,21 @@
void* run (void *arg) {
  struct Targ * targ = (struct Targ * )arg;
  // SArrayLockFreeQueue<struct Item> *queue = QFactory::createArrayLockFreeQueue<struct Item> (targ->key, 10);
  LockFreeQueue<struct Item> *queue = QueueFactory::createQueue<struct Item> (targ->key, qsize);
 // LockFreeQueue<struct Item> *queue = QueueFactory::createQueue<struct Item> (targ->key, qsize);
  SHMQueue<struct Item> *queue = new SHMQueue<struct Item>(targ->key, qsize);
  struct Item item;
  struct timespec timeout = {5, 0};
  int i = 0;
  while((queue->pop_timeout(item, &timeout)) ) {
  while(!stop && (queue->pop_timeout(item, &timeout)) ) {
    printf("consumer(%d) 出队: {%d, %d}\n", targ->key, item.pic, item.info);
   // cout <<  item.pic << endl;
    i++;
    
  }
  delete queue;
  return (void *)i;
}
@@ -50,7 +51,6 @@
  for (i = 0; i< NTHREADS; i++) {
    targs[i].key = i;
    pthread_create(&tids[i], NULL, run, (void *)&targs[i]);
    sleep(1);
  }
  for (i = 0; i< NTHREADS; i++) {
test/multiple_queue_productor
Binary files differ
test/multiple_queue_productor.c
@@ -6,12 +6,10 @@
#define NTHREADS 4 
struct Targ targs[NTHREADS];
size_t qsize = 16;
bool stop = false;
void sigint_handler(int sig) {
  cerr << "sigint_handler" << endl;
  mm_destroy();
  exit(0);
  stop = true;
}
void* run (void *arg) {
@@ -19,10 +17,9 @@
  struct Targ * targ = (struct Targ * )arg;
 // cerr << "productor key="<<targ->key << endl;
  err_msg(0, "productor key = %d\n", targ->key );
  //SLinkedLockFreeQueue<struct Item> *queue = QFactory::createLinkedLockFreeQueue<struct Item> (targ->key, 10);
  //SArrayLockFreeQueue<struct Item> *queue = QFactory::createArrayLockFreeQueue<struct Item> (targ->key, 10);
  
  LockFreeQueue<struct Item> *queue = QueueFactory::createQueue<struct Item> (targ->key, qsize);
 // LockFreeQueue<struct Item> *queue = QueueFactory::createQueue<struct Item> (targ->key, qsize);
 SHMQueue<struct Item> *queue = new SHMQueue<struct Item>(targ->key, qsize);
  /* Transfer blocks of data from stdin to shared memory */
  int end = targ->end;
  struct Item item;
@@ -32,7 +29,7 @@
  item.pic = i;
  item.info = i;
  while((end == -1 || (i < end) ) && (queue->push(item)) ) {
  while(!stop && (end == -1 || (i < end) ) && (queue->push(item)) ) {
    item.pic = i;
    item.info = i;
    printf("productor(%d) 入队:{%d, %d}\n", targ->key, item.pic,  item.info);
@@ -40,6 +37,7 @@
    i++;
    
  }
  delete queue;
  return (void *)i;
}
@@ -77,7 +75,7 @@
  }
  
  //destroy();
  mm_destroy();
  cerr << "productor quit" << endl;
  exit(EXIT_SUCCESS);
}
test/single_consumer
Binary files differ
test/single_consumer.c
@@ -3,33 +3,36 @@
 
int key = 1;
bool stop = false;
void sigint_handler(int sig) {
  destroy(key);
  exit(0);
  stop = true;
}
int main(int argc, char *argv[])
{
   
  int qsize = 16;
 
  signal(SIGINT,  sigint_handler);
  /* Get IDs for semaphore set and shared memory created by writer */
  //SAbstractQueue<struct Item> *queue = QFactory::createQueue<struct Item> (1, 10);
  LockFreeQueue<struct Item> *queue = QueueFactory::createQueue<struct Item> (key, qsize);
  // SHMQueue<struct Item, 3> *queue = new SHMQueue<struct Item, 3>(qsize);
  SHMQueue<struct Item> *queue = new SHMQueue<struct Item>(key, qsize);
  //LockFreeQueue<struct Item> *queue = QueueFactory::createQueue<struct Item> (key, qsize);
  /* Transfer blocks of data from shared memory to stdout */
   
  struct timespec timeout = {10, 0};
  struct Item item;
  while(queue->pop(item)) {
    cout <<  item.pic  << endl;
  while(!stop && queue->pop(item)) {
    cout << "出队:" << item.pic << ", " << item.info << endl;
    //cout <<  item.pic  << endl;
    //sleep(1);
  }
  destroy(key);
  delete queue;
  mm_destroy();
  cerr << "consumer quit" << endl;
  exit(EXIT_SUCCESS);
}
test/single_productor
Binary files differ
test/single_productor.c
@@ -2,14 +2,11 @@
 
using namespace std;
int key = 1;
bool stop = false;
void sigint_handler(int sig) {
  cerr << "sigint_handler" << endl;
  destroy(key);
  exit(0);
  printf("sigint_handler\n");
  stop = true;
}
int main(int argc, char *argv[])
@@ -27,9 +24,8 @@
    start = atoi(argv[1]);
    end = atoi(argv[2]);
  }
  //SAbstractQueue<struct Item> *queue = QFactory::createQueue<struct Item> (1, 10);
  LockFreeQueue<struct Item> *queue = QueueFactory::createQueue<struct Item> (key, qsize);
  //LockFreeQueue<struct Item> *queue = QueueFactory::createQueue<struct Item> (key, qsize);
  SHMQueue<struct Item> *queue = new SHMQueue<struct Item>(key, qsize);
  
  /* Transfer blocks of data from stdin to shared memory */
@@ -39,17 +35,19 @@
  item.pic = i;
  item.info = i;
  //while((end == -1 || (i < end) ) && (queue->add(item)) ) {
  while((queue->push(item)) ) {
  while(!stop && (queue->push(item)) ) {
    item.pic = i;
    item.info = i;
    // cout << "入队:" << item.pic << ", " << item.info << endl;
    cout <<  item.pic << endl;
    cout << "入队:" << item.pic << ", " << item.info << endl;
   // cout <<  item.pic << endl;
    i++;
    
  }
  destroy(key);
  delete queue;
  mm_destroy();
  cerr << "productor quit" << endl;
  exit(EXIT_SUCCESS);
}
test/test.h
@@ -1,7 +1,7 @@
#include "usg_common.h"
#include "usg_typedef.h"
#include "lock_free_queue.h"
#include "queue_factory.h"
#include "shm_queue.h"
//#include "queue_factory.h"
#include <pthread.h>
@@ -25,8 +25,8 @@
 //   //queue->~LockFreeQueue();
    // delete queue;
    QueueFactory::dropQueue<struct Item>(key);
    mm_destroy();
    //QueueFactory::dropQueue<struct Item>(key);
    // mm_destroy();
    
}
test/test_queue
old mode 100644 new mode 100755 Binary files differ
test/test_queue.c
@@ -9,8 +9,8 @@
    struct Item item;
    size_t qsize = 16;
      LockFreeQueue<struct Item> *queue = QueueFactory::createQueue<struct Item> (key, qsize);
      //LockFreeQueue<struct Item> *queue = QueueFactory::createQueue<struct Item> (key, qsize);
    SHMQueue<struct Item> *queue = new SHMQueue<struct Item>(key, 16);
    // LockFreeQueue<struct Item> queue(16);
    for(i = 0; i < qsize; i++) {
@@ -19,13 +19,13 @@
        }
    }
    // for(i = 0; i < qsize; i++) {
    for(i = 0; i < qsize; i++) {
        
    //     //queue.dequeue(item);
        //queue.dequeue(item);
        
    //     item = (*queue)[i];
    //     cout << "i=" << i << " item " << item.pic << "," << item.info << endl;
    // }
        item = (*queue)[i];
        cout << "i=" << i << " item " << item.pic << "," << item.info << endl;
    }
     
@@ -38,7 +38,7 @@
        i++;
    }
    destroy(key);
    delete queue;
    mm_destroy();
}
test/test_timeout
Binary files differ
test/test_timeout.c
@@ -4,17 +4,10 @@
using namespace std;
int key = 2;
size_t qsize = 16;
// 销毁共享内存和信号
void sigint_handler(int sig) {
  destroy(key);
  exit(0);
}
void productor() {
   LockFreeQueue<struct Item> *queue = QueueFactory::createQueue<struct Item> (key, qsize);
   // LockFreeQueue<struct Item> *queue = QueueFactory::createQueue<struct Item> (key, qsize);
   SHMQueue<struct Item> *queue = new SHMQueue<struct Item>(key, qsize);
  /* Transfer blocks of data from stdin to shared memory */
  struct Item item;
  struct timespec timeout = {5, 0};
@@ -43,11 +36,12 @@
    i++;
    
  }
  delete queue;
}
void consumer() {
  LockFreeQueue<struct Item> *queue = QueueFactory::createQueue<struct Item> (key, qsize);
   SHMQueue<struct Item> *queue = new SHMQueue<struct Item>(key, qsize);
  /* Transfer blocks of data from shared memory to stdout */
   
  while(1) {
@@ -68,17 +62,19 @@
    }
   
  }
  delete queue;
}
int main(int argc, char *argv[])
{
   
   
  signal(SIGINT,  sigint_handler);
  
  productor();
  consumer();
   
  // 销毁共享内存和信号
  destroy(key);
  // 销毁共享内存
  mm_destroy();
  exit(EXIT_SUCCESS);
}