线程同步问题

soliddream66 2010-04-03 11:47:43
说明:比较通用的模型,输入和输出队列,线程不停的从输入数据取数据放到输出队列里,类的用户不断的向这个类添加数据,以及获取数据。添加数据以及获取数据不在一个线程。Over~


可以想象如下伪代码

class server
{
queue i;
queue o;
thread()
{
o = process(i);
}
addbuffer();
getbuffer();
}

thread client1()
{
addbuffer();
}

thread client2()
{
getbuffer();
}
}

两个队列实际声明如下:
std::map<Role, std::deque<BufferStamped>> m_iBuffer;
std::map<Role, std::deque<BufferStamped>> m_oBuffer;

我在线程以及addbuffer,getbuffer加了个锁,结果导致死锁了。

应该如何线程同步呢?

ps。或者是通过线程发送消息的方式规避线程同步问题?添加数据好说,但是而用户程序向线程发送消息获取线程维护的数据似乎很难办,发送消息获取数据无法立即返回。

...全文
133 9 打赏 收藏 转发到动态 举报
写回复
用AI写文章
9 条回复
切换为时间正序
请发表友善的回复…
发表回复
newasoft 2010-04-07
  • 打赏
  • 举报
回复
一个生产,一个消费的不需要线程同步。
做个循环队列即可,设置读的指针和写的指针的位置。
或者利用链表,增加的数据放到链表后面的位置,去数据从链表头取,只要两个指针不重合就可以取数据。
cattycat 2010-04-03
  • 打赏
  • 举报
回复
注意加锁的顺序保持一致,在读取和写入的队列都要加锁,获取锁的顺序要一致,可以看看进程的互斥。
mutex应该可以满足你的要求,或用Semaphore。
jackyjkchen 2010-04-03
  • 打赏
  • 举报
回复
楼主的程序结构和我刚做完的项目很像,我那里5个线程,4个队列,每两个线程维护一个队列,就是在修改和读取队列时加上锁,没有问题
jackyjkchen 2010-04-03
  • 打赏
  • 举报
回复
就用读写锁控制同步吧,消息模式不好搞。

死锁是不可能的吧,除非有逻辑漏洞或者忘记了解锁
soliddream66 2010-04-03
  • 打赏
  • 举报
回复
[Quote=引用 6 楼 graymole2010 的回复:]

呵呵,是不是有三个线程:
线程1:调用addbuffer,把数据放到queue i中;
线程2:调用getbuffer,从queue i获得数据;
线程3:process,处理queue i的数据,然后放到queue o;
由于queue是在队尾加数据,队首取数据,一般冲突的概率不是很大,运行时间不长不会出现问题。
最简单的加锁方法是在process、addbuffer与getbuff……
[/Quote]

很有道理,不过我的处理任务比较复杂些。

首先是map关联角色和buffer,其次在线程中,得等到所有角色的buffer都获得之后才开始处理。

不过变通一下,WaitForMultipleObjects或许很有效果。

soliddream66 2010-04-03
  • 打赏
  • 举报
回复
输出队列m_oBuffer在两个地方使用,一个是线程,另一个是GetBuffer。线程用于添加数据,每隔10ms执行一次(保证m_oBuffer添加比较迅速)。而GetBuffer用于获取数据(大约每隔40ms执行一次)
在这种环境中使用的话,线程添加数据是m_oBuffer的尾部push_back,而GetBuffer获取数据是在m_oBuffer的begin部分,我觉得只要队列是一个线程只管添加,另一个线程只管获取就不需要线程同步了,输入队列m_iBuffer同理。

GrayMole2010 2010-04-03
  • 打赏
  • 举报
回复
呵呵,是不是有三个线程:
线程1:调用addbuffer,把数据放到queue i中;
线程2:调用getbuffer,从queue i获得数据;
线程3:process,处理queue i的数据,然后放到queue o;
由于queue是在队尾加数据,队首取数据,一般冲突的概率不是很大,运行时间不长不会出现问题。
最简单的加锁方法是在process、addbuffer与getbuffer加上同一个mutex锁。这样,效率会比较低一些,
addbuffer会把getbuffer锁住。
另一种做法是针对queue i与queue o各使用一个mutex锁。
还可以考虑使用event,addbuffer后产生一个event,通知process可以取数据处理;process处理完数据放到queue o后,可以产生一个event通知getbuffer可以取数据。
cattycat 2010-04-03
  • 打赏
  • 举报
回复
哪是巧合了,容易造成数据不一致。
soliddream66 2010-04-03
  • 打赏
  • 举报
回复
去掉线程同步,运行的时候居然没有挂,我现在观察观察有没有什么问题。

64,637

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧