社区
C++ 语言
帖子详情
关于stl中std:queue线程安全问题
drinker_linux
2010-02-04 04:53:54
各位高手,请指教,谢谢!
c++-->stl中的std::queue是非线程安全的。
请问:1.为什么不作成线程安全的
2.到底什么是线程安全什么是线程非安全的,对于队列来说。一个线程读,一个线程写,不加锁会出什么问题。
...全文
2863
34
打赏
收藏
关于stl中std:queue线程安全问题
各位高手,请指教,谢谢! c++-->stl中的std::queue是非线程安全的。 请问:1.为什么不作成线程安全的 2.到底什么是线程安全什么是线程非安全的,对于队列来说。一个线程读,一个线程写,不加锁会出什么问题。
复制链接
扫一扫
分享
转发到动态
举报
写回复
配置赞助广告
用AI写文章
34 条
回复
切换为时间正序
请发表友善的回复…
发表回复
打赏红包
jinchuan97
2011-02-14
打赏
举报
回复
试试下面这段代码,可以发现不加锁的问题了(运行一段时间后出现内存非法访问导致程序崩溃)
std::queue<BYTE*> g_queue;
::CRITICAL_SECTION g_cs;
DWORD WINAPI th1( LPVOID lpVoid )
{
while( true )
{
BYTE* buf = new BYTE[100];
//::EnterCriticalSection( &g_cs );
g_queue.push( buf );
//::LeaveCriticalSection( &g_cs );
Sleep(10);
}
}
DWORD WINAPI th2( LPVOID lpVoid )
{
while( true )
{
//::EnterCriticalSection( &g_cs );
if( g_queue.size()>0 )
{
BYTE* buf = g_queue.front();
g_queue.pop();
delete []buf;
}
//::LeaveCriticalSection( &g_cs );
Sleep(10);
}
}
int main()
{
::InitializeCriticalSection( &g_cs );
::CreateThread( NULL, 0, th1, NULL, 0, NULL );
::CreateThread( NULL, 0, th2, NULL, 0, NULL );
system("pause");
}
yangyunzhao
2010-10-23
打赏
举报
回复
[Quote=引用 25 楼 drinker_linux 的回复:]
那么怎么才能出问题请问,
[/Quote]
出问题不是指程序抛异常吧。
应该是说程序运行效果和自己的想法不一致就叫出异常吧。不加锁几乎必然出问题,只是怎么出现而已。
你试试在多线程情况下,用用迭代器,不加锁。估计很快就出问题了
tompaz
2010-10-13
打赏
举报
回复
int读写简单,搞个复杂点的类试试就知道了
taodm
2010-02-09
打赏
举报
回复
呃,要向一个还不知道并发冲突是何物的人讲清楚可还真是实在很困难的。
如果楼主人品足够持续恒定一直好,你的代码就没啥问题。
必成桂
2010-02-04
打赏
举报
回复
当然不是线程安全的。
queue的底层实现一般是vector或者是deque。写操作的时候还是需要加锁的。
drinker_linux
2010-02-04
打赏
举报
回复
我已经试过,不管是去掉if(qqq.size()>1000)continue; 不管是怎么弄,程序都会正常运行啊
jackyjkchen
2010-02-04
打赏
举报
回复
[Quote=引用 27 楼 drinker_linux 的回复:]
可是这样的话,这个队列的大小启不是不确定上限了,如果无限的push数据,这样是不合理的吧。我先安你说的办,去掉那两行
[/Quote]
入队线程用低优先级,或者加个sleep,让它运行比出队慢即可。
drinker_linux
2010-02-04
打赏
举报
回复
可是这样的话,这个队列的大小启不是不确定上限了,如果无限的push数据,这样是不合理的吧。我先安你说的办,去掉那两行
jackyjkchen
2010-02-04
打赏
举报
回复
[Quote=引用 25 楼 drinker_linux 的回复:]
那么怎么才能出问题请问,
[/Quote]
if(qqq.size()>1000)
continue;
这一句去掉,有了这一句,你真正运行了不过N毫秒……
drinker_linux
2010-02-04
打赏
举报
回复
那么怎么才能出问题请问,
jackyjkchen
2010-02-04
打赏
举报
回复
if(qqq.size()>1000)
continue;
20分钟……真正进入队列的数据才1000个,后面都在空转
drinker_linux
2010-02-04
打赏
举报
回复
大家请看,我写了两个线程程序,一个写,一个读,已经运行了20分钟了,还没有出任何问题,为什么?
1 #include <stdio.h>
2 #include <pthread.h>
3 #include <queue>
4
5 using namespace std;
6
7 queue<int> qqq;
8 pthread_t pt1,pt2;
9
10 void *thread1(void *arg)
11 {
12 static int num = 0;
13 while(true)
14 {
15 if(qqq.size()>1000)
16 continue;
17 printf("thread1 push num=%d\n",num);
18 qqq.push(num++);
19 if(num >0x0FFFFFFF)
20 num = 0;
21 }
22 }
23
24 void *thread2(void *arg)
25 {
26 int num = 0;
27 while(true)
28 {
29 if(qqq.empty())
30 continue;
31 num = qqq.front();
32 qqq.pop();
33 printf("thread2 pop num=%d\n",num);
34 }
35 }
36
37
38 int main()
39 {
40 pthread_create(&pt1,NULL,thread1,NULL);
41 pthread_create(&pt2,NULL,thread2,NULL);
42 pthread_join(pt1,NULL);
43 pthread_join(pt2,NULL);
44 return 0;
45 }
yshuise
2010-02-04
打赏
举报
回复
queue不加锁的效率都比较低。
jackyjkchen
2010-02-04
打赏
举报
回复
STL的队列算是最简单的设计了,许多库里都有自己的队列,ACE连线程库都有,但它的队列同样没有内部锁,可见队列搞内部线程安全是划不来的
yshuise
2010-02-04
打赏
举报
回复
现在是多核时代了,我想对象大量的数据操作,是很意义的。
yshuise
2010-02-04
打赏
举报
回复
对于13楼的兄弟,我刚才忘说了,我说的队列是先进先出队列
===========
队列还有其它方式?
jackyjkchen
2010-02-04
打赏
举报
回复
[Quote=引用 14 楼 drinker_linux 的回复:]
那么请问能自己实现一个不用加锁即可实现线程安全的队列吗?
[/Quote]
当然可以,意义不大,所有改变队列状态的操作都加锁,就可以保证队列不被破坏,但是效率会下降,而且某些时候仍然需要同步……
traceless
2010-02-04
打赏
举报
回复
这个“锁”在lZ这是个什么概念。。。
yshuise
2010-02-04
打赏
举报
回复
那么请问能自己实现一个不用加锁即可实现线程安全的队列吗?
==============
多线程我还是初学者,不清楚。
drinker_linux
2010-02-04
打赏
举报
回复
对于13楼的兄弟,我刚才忘说了,我说的队列是先进先出队列
加载更多回复(14)
优先级队列对C ++使用环形缓冲区,固定长度-C/C++开发
不是
线程安全
的C ++ 11实现完全可移植自排序,例如
std
:: set基本用法整个队列的实现包含在一个标头ring_list.h
中
。 简单示例:#include“ ring_
queue
.h”容器:: Ring
Queue
q; q.push(2); q.push(1); assert(q....
关于C++的
std
::
queue
内存不释放的
问题
的解决方法
我们使用
std
::
queue
来存放一些临时的缓冲数据,然后有一个线程不断地从
queue
里取数据,写入到文件
中
,之后会调用pop()函数将数据弹出。但是很奇怪的地在弹出的过程
中
,程序的内存占用丝毫没有减少。查了一些资料后...
std
::
queue
std
::
queue
, 入队列的方法是:
std
::
queue
::push(), 出队列的方法是:
std
::
queue
::pop(), 为了异常安全, 这个方法返回void, 所以通常调用
std
::
queue
::front(), 查看队列头部的元素, 然后调用
std
::
queue
::pop(), 让...
C++并发实战12:
线程安全
的
queue
1 首先看下
STL
中
的
queue
的接口: template > class
queue
{ public: explicit
queue
(const Container&); explicit
queue
(Container&& = Container()); template explicit
queue
(const Alloc&); template
C++11:基于
std
::unordered_map和共享锁构建
线程安全
的map
前一篇博客《C++:基于
std
::
queue
和
std
::mutex构建一个
线程安全
的队列》
中
,我们实现了一个
线程安全
的队列,本文我们说说如何实现一个
线程安全
的map。 在上一篇博客
中
,实现threadsafe_
queue
主要是依赖
std
::mutex...
C++ 语言
64,637
社区成员
250,559
社区内容
发帖
与我相关
我的任务
C++ 语言
C++ 语言相关问题讨论,技术干货分享,前沿动态等
复制链接
扫一扫
分享
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++
技术论坛(原bbs)
社区管理员
加入社区
获取链接或二维码
近7日
近30日
至今
加载中
查看更多榜单
社区公告
请不要发布与C++技术无关的贴子
请不要发布与技术无关的招聘、广告的帖子
请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下
试试用AI创作助手写篇文章吧
+ 用AI写文章