队列并发两个不同的锁:一个用于 enqueue() 以保护同时排队的多个线程
如果队列已满,Add(enqueue)将跳过(返回)插入。如果队列为空,则删除(出列)将跳过删除。
我使用doRandon()生成了一堆0到1之间的随机数。我使用这些数字来决定是否添加/删除。
性能:我已尝试使用静态/动态线程分配测试队列。的执行时间
//g++ -std=c++0x -pthread -o block blocking.cpp;./block
#include <iostream>
#include <thread>
#include <mutex>
#include <atomic>
#include <random>
#include <stdio.h>
#include <time.h>
#include <stdlib.h>
#include <ctime>
#include <condition_variable>
using namespace std;
#define NUMBER_OF_THREADS 1
#define NUMBER_OF_OPERATIONS 10000000
#define QUEUE_CAPACITY 1000000
std::vector<double> getRandom();
template <class T> class BoundedQueue {
private:
T * array;
int head, tail, capacity;
std::mutex enqLock, deqLock;
std::atomic<long> sharedCounter;
std::condition_variable notEmptyCondition, notFullCondition;
public:
void staticAllocation(double randomNumbers[], int threadID);
void dynamicAllocation(double randomNumbers[]);
void add (T x);
BoundedQueue ();
void remove ();
};
template <class T> BoundedQueue<T>::BoundedQueue () {
capacity = QUEUE_CAPACITY;
array = new T[capacity];
head = 0;
tail = 0;
sharedCounter = 0;
}
template <class T> void BoundedQueue<T>::add (T x) {
enqLock.lock();
if (tail - head == capacity) {
enqLock.unlock();
return;
}
array[tail % capacity] = x;
tail++;
enqLock.unlock();
}
template <class T> void BoundedQueue<T>::remove() {
deqLock.lock();
if (tail - head == 0) {
deqLock.unlock();
return;
}
T result = array [head % capacity];
head++;
deqLock.unlock();
}
template <class T> void BoundedQueue<T>::dynamicAllocation(double randomNumbers[]) {
long i = 0;
while (i < QUEUE_CAPACITY) {
i = sharedCounter.fetch_add(1, std::memory_order_relaxed);
if(randomNumbers[i] <= 0.5) add(0);
else remove();
}
}
template <class T> void BoundedQueue<T>::staticAllocation (double randomNumbers[], int threadID) {
int split = NUMBER_OF_OPERATIONS / NUMBER_OF_THREADS;
for (int i = threadID * split; i < (threadID * split) + split; i++) {
if(randomNumbers[i] <= 0.5) add(0);
else remove();
}
}
std::vector<double> getRandom() {
std::vector<double> numbers;
std::random_device rd;
std::mt19937 gen(rd());
std::uniform_real_distribution<> dis(0,1);
for(int i = 0; i < NUMBER_OF_OPERATIONS; i++) numbers.push_back(dis(gen));
return numbers;
}
int main () {
BoundedQueue<int> bQ;
std::vector<double> temp = getRandom();
double* randomNumbers = &temp[0];
std::thread myThreads[NUMBER_OF_THREADS];
clock_t begin = clock();
for(int i = 0; i < NUMBER_OF_THREADS; i++) {
myThreads[i] = std::thread ( [&] {bQ.dynamicAllocation(randomNumbers); });
}
for(int i = 0; i < NUMBER_OF_THREADS; i++) {
if(myThreads[i].joinable()) myThreads[i].join();
}
clock_t end = clock();
cout << double(end-begin) * 1000 / CLOCKS_PER_SEC;
return 0;
}
这里没有相似之处。请注意,所有的线程几乎都被序列化了,因为您在函数开始时获取了一个锁,并在函数结束时释放了它。
尽管由于缺乏并行性,工作在线程之间进行分配,但锁定/解锁开销占主导地位,总体而言,与单线程相比,执行时间较长。
因此,存在并发性,但没有并行性,我们只是付出了同步的代价,而没有性能优势。
我编写了一个简单的类,我计划将其扩展为客户端套接字编程应用程序的一部分。类涉及一个BlockingQueue(我从这里复制了代码:相当于Java的BlockingQueue的C++)。当我创建了下面的包装类的一个实例后,我打算让它生成一个单独的线程,该线程只需执行BlockingQueue上阻塞的printer()函数,直到有一个或多个字符串可用,然后它只需将字符串打印到控制台窗口。在我的预期应用
我需要一个库或我们的软件工具,可以: 1)将线程/作业/任务(任何东西--如果需要,我们可以重写代码,我们在mintue有线程对象)放入像system这样的队列中2)我们可以定义同时最多运行多少线程3)线程完成后,线程从队列中移除,这样GC就可以移除所有涉及的实体。 我正在进行大量阅读,发现ExecutorService(Executors.newFixedThreadPool(5);)但问题可能
在使用TensorFlow进行异步计算时,队列是一种强大的机制。 正如TensorFlow中的其他组件一样,队列就是TensorFlow图中的节点。这是一种有状态的节点,就像变量一样:其他节点可以修改它的内容。具体来说,其他节点可以把新元素插入到队列后端(rear),也可以把队列前端(front)的元素删除。 为了感受一下队列,让我们来看一个简单的例子。我们先创建一个“先入先出”的队列(FIFOQ
问题 你有一个线程队列集合,想为到来的元素轮询它们, 就跟你为一个客户端请求去轮询一个网络连接集合的方式一样。 解决方案 对于轮询问题的一个常见解决方案中有个很少有人知道的技巧,包含了一个隐藏的回路网络连接。 本质上讲其思想就是:对于每个你想要轮询的队列,你创建一对连接的套接字。 然后你在其中一个套接字上面编写代码来标识存在的数据, 另外一个套接字被传给 select() 或类似的一个轮询数据到达
问题内容: 也许这是一个愚蠢的问题,但我似乎找不到一个明显的答案。 我需要一个仅包含唯一值的并发FIFO队列。尝试添加队列中已经存在的值只会忽略该值。如果不是为了线程安全,那将是微不足道的。在Java中是否存在数据结构,或者在Interweb上是否存在代码snipit表现出这种行为? 问题答案: 如果您想要比完全同步更好的并发性,那么我知道有一种方法可以使用ConcurrentHashMap作为支
本文向大家介绍C#线程队列用法实例分析,包括了C#线程队列用法实例分析的使用技巧和注意事项,需要的朋友参考一下 本文实例讲述了C#线程队列用法。分享给大家供大家参考。具体如下: 希望本文所述对大家的C#程序设计有所帮助。