首页
社区
课程
招聘
[求助]多线程的数据怎么同步?
发表于: 2013-6-6 15:00 7997

[求助]多线程的数据怎么同步?

2013-6-6 15:00
7997
正在写一个程序
涉及到多线程同步的问题
具体的过程可以抽象为这样(线程A和B都不是主线程,是主线程开启的)
线程A 获取事物C的属性变量M 这个属性变量第一次设置为0 即M(初始)=0 (后面设置为从线程B中处理后的数据。)事物A先判断线程B是否启动,如果没启动则启动线程B 根据事物C的属性变量M 执行操作A的动作,接着执行操作B的动作 。[动作B的操作可以对事物C进行消费。比如inc(事物C)]
循环执行线程A的动作直到线程退出。线程B 判断事物C是否存在,不存在则创建(生产),获取事物新C的属性变量M,并且存储该数据到 事物C属性的变量M当中 即 M=新获取属性变量(C)
执行操作B的动作。动作B的操作可以对事物C进行消费。比如inc(事物C) 当事物C的某个数据=0
的时候 C 就被消费完了。循环执行线程B的动作直到线程退出。现在的问题就是 事物C的属性变量M 同时被两个线程操作 而且中间还有很多的其他步骤,我用了很多方法要么线程 堵塞 ,要么线程无法同步请问应该用什么方式同步?怎么同步?
伪代码 --不知道是不是可以这么说
创建线程A
1、M=线程B中获得的M(第一次为0,后面为线程B中获得)
2、判断(线程B是否启动)
3、没有启动 则启动线程B
4、执行动作A(M)   ----消费这个数据消费完之后才允许它改变
5、执行动作B(inc(事物C))   消费
6、回到1 直到线程A退出
创建线程B
1、判断是否存在(事物C)
2、不存在则创建(事物C)     生产
3、M=得到变量(事物C)----------- 不断生产这个 数据 并且给A进程消费
4、执行动作B(inc(事物C))   消费
5、回到1 直到线程B退出
如何顺利的同步这两个线程?我用了
EnterCriticalSection(My);  
try
finally
LeaveCriticalSection(My); //离开临界区
end;
结果线程B被阻塞了。。
主要的问题就是创建事物c之后 M要被重置(生产)。我是希望这个生产和

消费可以协调起来
B线程生产 A线程消费 A消费完 再B线程生产 这个应该怎么实现呢?
C++ DELPHI VB 易 JAVA(只要不是汇编)或者给个类似的伪代码都可以

http://bbs.pediy.com/showthread.php?t=173161
这个是一个其中的解决办法
但是我不知道怎么实现。。。郁闷啊

[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

收藏
免费 0
支持
分享
最新回复 (12)
雪    币: 160
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
DWORD WaitForSingleObject(
  HANDLE hHandle,
  DWORD dwMilliseconds
);
可以等待线程直到其退出。
2013-6-6 19:23
0
雪    币: 6092
活跃值: (699)
能力值: ( LV4,RANK:45 )
在线值:
发帖
回帖
粉丝
3
我写了一个简单的模拟器
密码是kanxue
有兴趣的去研究下
两个代码的差别就一行
if (shiwuc.m=0) and (shiwuc.c=0) then  //两个都消费完才开始生产 就没冲突 但是如果两个都消费完这样无效率 因为A要等B B要等A浪费了时间(两个都要消费完嘛,A消费好了 还要等B消费完才能 继续 B也是一样)
if  shiwuc.c=0 then  //这里C消费消费完毕之后 (shiwuc.m 这个数据顺利的给A线程消费让A消费完)同时B线程 重新生产 让B消费掉 shiwuc.c  但是象我这么写 会产生冲突  问题就是如何解决这个冲突(B消费完了 重新产生了 shiwuc.m 把原先的数据shiwuc.m 覆盖了 需要把原先的数据保存起来 让A消费完的 B此时可以消费新的shiwuc.c 并且 把shiwuc.m 数据保存起来等A消费完 )大家看完程序之后就知道了
主要是怎么修改成 (if  shiwuc.c=0 then  ) 这样 而且两个线程不冲突
A线程可以顺利的消费完之前没消费的,解决冲突问题
上传的附件:
2013-6-6 20:11
0
雪    币: 6092
活跃值: (699)
能力值: ( LV4,RANK:45 )
在线值:
发帖
回帖
粉丝
4
没人回复,貌似要用队列
2013-6-7 07:54
0
雪    币: 1837
活跃值: (1761)
能力值: ( LV12,RANK:230 )
在线值:
发帖
回帖
粉丝
5
锁、信号量
2013-6-7 08:30
0
雪    币: 6092
活跃值: (699)
能力值: ( LV4,RANK:45 )
在线值:
发帖
回帖
粉丝
6
这样会产生等待时间和浪费 还有这个锁是对什么加锁,如果是信号量的话 怎么使用?
这样的回复也太简单了
2013-6-7 09:06
0
雪    币: 49
活跃值: (19)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
7
侯捷 有一本 多线程编程 有电子版的 建议看看

楼主描述的线程同步过程太过于冗余了 不精简 看不懂
本想看看代码 不过似乎是PASCAL的 帮不上忙了
2013-6-7 09:34
0
雪    币: 65
活跃值: (112)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
8
简单说就是锁

先搞清楚什么是锁再说

论坛有锁相关话题
2013-6-7 09:53
0
雪    币: 6092
活跃值: (699)
能力值: ( LV4,RANK:45 )
在线值:
发帖
回帖
粉丝
9
或许是我表述不好吧
简单说
线程 A 消费 两个资源 线程B生产两个资源 消费一个资源 B生产的条件是一个重要资源被消费完即可开始生产 shiwuc.c=0,但是目前的主流都是等待A消费完 两个资源都被消费了 才开始生产这样就有等待时间
如果只考虑重要资源被消费完就生产 会导致新生产的数据覆盖了原先的另外一个资源(shiwuc.c和shiwuc.w都是一个结构体的,重新创建就会覆盖原先的),这样A消费的一个资源就混乱了,需要一个数据结构保存重要资源被消费完的时候另外一个资源 让A消费完的。等A消费完了也可以一起消费重要资源 加速B生产,这样你应该明白了?
2013-6-7 10:01
0
雪    币: 6092
活跃值: (699)
能力值: ( LV4,RANK:45 )
在线值:
发帖
回帖
粉丝
10
代码很简单的。又没几行,这个是最简化的东西了。
无非就是创建线程,数字加减,pascal的有那么难认识么
2013-6-7 10:03
0
雪    币: 6092
活跃值: (699)
能力值: ( LV4,RANK:45 )
在线值:
发帖
回帖
粉丝
11
这个问题是涉及到锁和数据结构的
锁的是数据结构 不是数据
如果简单给数据加锁是同步了但是效率下降了 而且甚至可以不加锁 只需要判断两个完全消费完就可以了
所以问题不在锁在数据结构
但是delphi怎么实现我不会
2013-6-7 10:05
0
雪    币: 6092
活跃值: (699)
能力值: ( LV4,RANK:45 )
在线值:
发帖
回帖
粉丝
12
问题已经解决,因为太简单就不发了
说下思路
在c++下用队列 然后push pop这样存储shiwuc.m里面的数据,也就是 被覆盖之前push 使用完之后pop,同时这个队列进行资源锁保证在一个时间内只被修改一次,
在delphi下有好几个思路 一个是自己定义队列 里面的操作也跟c++差不多 push pop ,还有一个简单的办法就是根据 tlist类的特点 把数据存储到里面 每次B生产的shiwuc.m追加到末尾 A消费list的顶部,消费完之后删除顶部 这样可以保证 A可以完整的按照次序消费 B生产的shiwuc.m,但是这个list是全局的 为了避免冲突 就要用一个锁  一个是通过CriticalSection event什么的都可以 具体的就是这样了。晚上睡个好觉了。
2013-6-7 23:11
0
雪    币: 49
活跃值: (19)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
13
所以说同步的东西本来就是临界区 信号 锁 同步
EASY
2013-6-8 15:34
0
游客
登录 | 注册 方可回帖
返回
//