以线程安全的方式每秒打印队列的当前元素数
Print current number of elements of queue in each second in thread safe manner
我想在多线程程序中每秒打印数据队列的当前元素数,如下所示:
queue<int> products;
void print(ostream& s)
{
cout << s.rdbuf();
cout.flush();
s.clear();
}
void printQueue()
{
while(true)
{
this_thread::sleep_for(chrono::seconds(1));
print(stringstream() << "Number of prouducts: " << products.size() << "n");
}
}
void producer(int i)
{ //adds data into queue in thread safe manner
}
void consumer(int i)
{/*removes data from queue in thread safe manner*/}
int main()
{
vector<thread> thrds;
for(int i = 0; i < 5; ++i)
thrds.push_back(thread(producer, i));
for(int i = 0; i < 4; ++i)
thrds.push_back(thread(consumer, i));
thrds.push_back(thread(printQueue));
for(auto& t : thrds)
t.join();
}
return 0;
}
printQueue - 这个函数线程安全吗?
多个线程访问两个资源:
-
std::cout
-
products
std::cout
的典型实现相对抗拒被多个线程访问,尽管它们不能保证输出不是交错的。不过,形式上没有同步,因此您的写入不是线程安全的。
关于products
,您的访问也不受任何互斥锁的保护,这也使这些访问非线程安全。在某些地方你只阅读大小并不重要。并不是说这种读取访问可能会破坏任何东西,但结果(即当您看到更改和看到的内容时)仍然未定义。
摘要:使用互斥锁保护共享资源。
在std::queue
合约上printQueue
线程安全与否。对于每个容器线程特定的方法行为,它们公开的方法将属于以下主要类别之一:
- 线程同步
- 线程安全
- 线程不安全(可以生成争用)
第三个意味着此调用永远不能在不受保护的环境中使用 - 这意味着,在此调用发生时,不能对容器的任何其他方法进行其他调用。1 和 2 之间的区别在于,对于第一个选项,您可以保证在另一个线程中修改新值后读取新值(具有合理的延迟)。Thread safe 不会为您提供此保证,但仍声明调用此方法不会将程序暴露给数据争用,并且保证读取旧值或新值,但没有未定义的行为。
对于标准容器作为std::queue
,它们的所有 const 方法是线程安全的,而非 const 方法是线程不安全的。由于您将调用线程不安全推送,因此您需要通过外部同步保护您的访问。
相关文章:
- 使用 <list> (错误 C2760) 打印队列的元素
- 从队列中删除第一个元素C++
- 如何在 c++ 中创建对的优先级队列.这会弹出具有最小值的元素.默认的弹出最大值
- 如何将元素从 STL 队列传递到函数?
- 如何实现唯一 id 队列,其中元素可以在 C++ 中"bumped"到顶部?
- 我们可以在队列前面以 O(1) 时间复杂度排队一个元素吗?
- C++ 数据结构队列:使用 for 循环查找队列中最大的元素
- 优先级队列(使用 pairs<int,int> ) 根据 for 循环迭代器的顶级元素
- 将元素从队列复制到堆栈
- 如何删除在没有STL的队列中存储在数组中的第一个字符串元素
- 打印队列元素的队列
- 如何获得向量队列的前部或顶部元素
- 从队列中编辑元素而不将其删除
- 在队列中,插入和删除后,被删除的元素也会出现在输出中.为什么
- 为具有可变元素(C++)的优先级队列确定最佳ADT
- 正在提取优先级队列的最后一个元素
- 当我插入元素时,C 优先级队列会崩溃
- 在队列中插入向量元素
- 我如何在队列中排序元素
- 将添加到队列的第一个元素作为 null 进行排序