| | |
| | | /// @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; |
| | |
| | | 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__ |
| | |
| | | // 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; |
| | |
| | | #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" |
| | |
| | | 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 |
| | |
| | | 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 |
| | |
| | | |
| | | } |
| | | |
| | | 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, |
| | |
| | | #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 |
New file |
| | |
| | | #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__ |
| | |
| | | # 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. |
| | | # |
| | |
| | | |
| | | |
| | | build: $(PROGS) |
| | | |
| | | |
| | | |
| | | # test1: $(LIBCOMMON) |
| | | |
| | |
| | | #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; |
| | | } |
| | | |
| | | |
| | |
| | | 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; |
| | | } |
| | | |
| | |
| | | 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++) { |
| | |
| | | #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) { |
| | |
| | | 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; |
| | |
| | | |
| | | 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); |
| | |
| | | i++; |
| | | |
| | | } |
| | | delete queue; |
| | | return (void *)i; |
| | | } |
| | | |
| | |
| | | } |
| | | |
| | | |
| | | //destroy(); |
| | | mm_destroy(); |
| | | cerr << "productor quit" << endl; |
| | | exit(EXIT_SUCCESS); |
| | | } |
| | |
| | | |
| | | |
| | | 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); |
| | | } |
| | |
| | | |
| | | |
| | | 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[]) |
| | |
| | | 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 */ |
| | |
| | | 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); |
| | | } |
| | |
| | | #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> |
| | | |
| | | |
| | |
| | | // //queue->~LockFreeQueue(); |
| | | // delete queue; |
| | | |
| | | QueueFactory::dropQueue<struct Item>(key); |
| | | mm_destroy(); |
| | | //QueueFactory::dropQueue<struct Item>(key); |
| | | // mm_destroy(); |
| | | |
| | | |
| | | } |
old mode 100644
new mode 100755
Binary files differ
| | |
| | | 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++) { |
| | | |
| | |
| | | } |
| | | } |
| | | |
| | | // 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; |
| | | } |
| | | |
| | | |
| | | |
| | |
| | | i++; |
| | | } |
| | | |
| | | |
| | | destroy(key); |
| | | delete queue; |
| | | mm_destroy(); |
| | | |
| | | } |
| | |
| | | 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}; |
| | |
| | | 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) { |
| | |
| | | } |
| | | |
| | | } |
| | | delete queue; |
| | | } |
| | | |
| | | int main(int argc, char *argv[]) |
| | | { |
| | | |
| | | |
| | | signal(SIGINT, sigint_handler); |
| | | |
| | | |
| | | productor(); |
| | | consumer(); |
| | | |
| | | // 销毁共享内存和信号 |
| | | destroy(key); |
| | | // 销毁共享内存 |
| | | mm_destroy(); |
| | | exit(EXIT_SUCCESS); |
| | | } |