线程同步的问题,找了很多相关的,没有结果,只好提出来(50分)

  • 主题发起人 主题发起人 ifeng
  • 开始时间 开始时间
好复杂.xeen是正解.我天天用的.
 
连xeen的也过复杂.特尔斐说可以做成一个线程比较正确,不过他没有明白,线程也是一
个内核对象,还需要建立别的对象干什么.再说了,即使另外建一个内核对象什么的也不
需要全局变量的,放在线程对象中就行了.
 
各位能不能给我一个用mutex的例子,
用两个线程举例
 
多谢barton指点,测试了xeen的方法,确实可以。又多学了一些。[:)]
 
我用了xeen的方法,在等待执行THREADA时,不能响应其他事件
如何处理??
 
其它事件?还有其它事件吗?你前面没说哦 [:(]如果是这样也好办。
换WaitForMultipleObjects函数,使用对象数组。根据返回的结果判断是发生了什么事件。
 
我现在是这样的
ThreadA的Execute
begin
FreeOnTerminate:=true;
if WaitForSingleObject(hMutex,INFINITE) = WAIT_OBJECT_0 then
begin
while not terminateddo
begin
.........
end;
end;
ReleaseMutex(hMutex);
end;

ThreadB的Execute
begin
FreeOnTerminate:=true;
if WaitForSingleObject(hMutex,INFINITE) = WAIT_OBJECT_0 then
begin
while not terminateddo
begin
.........
end;
end;
ReleaseMutex(hMutex);
end;

ThreadC的execute //ThreadC跟前面两个线程不相干的
begin
while not terminateddo
begin
.................
end;
end;

funA
begin
hMutex:=CreateMutex(nil,false,nil);
ThreadA:=TThreadA.create(false);
ThreadB:=TThreadB.create(false);
end;

funB
begin
ThreadC:=TThreadC.create(false);
end;
这样写不知有什么问题?正确的应怎么写?
 
越来越复杂了,还用上Mutex了。Mutex创建一个需要600+个时钟周期,只有跨进程才用的。
实不行用Semaphore好了。退出线程的时候ReleaseSemaphore
 
to barton
看来你对线程挺了解的,:)
那想我这样的,应该用什么呢?
semaphore怎么用?跟mutex一样用吗?到底哪个好?
不好意思,问了这么多问题
 
注意在funA中
funA
begin
hMutex:=CreateMutex(nil,false,nil);
ThreadA:=TThreadA.create(false);
只有等THreadA执行完了之后才能执行ThreadB,
如果用waitforsingleobject(ThreadA.handle,.....),程序就没有响应了
ThreadB:=TThreadB.create(false);
end;

 
Semaphore的缺点太多.
何况Semaphore本意是用在另一种环境的.
 
那到底用什么呢?讨论讨论
 
本来不想说了,想想生气,不吐不快。
to real_clq:
>>真正的同步要用互斥量.
兄弟,什么叫真正的同步?什么叫假的同步?本菜鸟只知道互锁同步、关键代码段同步、内
核对象同步,怎么从没听说同步还分真假?内核对象中有进程、线程、作业、文件、控制台
输入、文件改动、事件、可待定时器、信标、互斥共十个,互斥是万不得已才用的内核对
象。其中,进程、作业、文件、控制台输入、文件改动显然在专门的条件下才使用的,剩
下的内核对象中只有互斥对象是在需要跨进程同步时才使用,而且花费的机器周期非常长,
所以一般不用。
>>Semaphore的缺点太多.
>>何况Semaphore本意是用在另一种环境的.
缺点太多?兄弟,我恐怕你半点缺点也说不出来吧?别说没有,就是有我相信你也指不出
来。semaphore(信标)本意在什么环境下使用?我相信你也说不出来。Semaphore和Event
几乎一样,差别只有两点:Event只有两种状态,而且在置位后可以自动复位也可以手工复
位;Semaphore可以设定一个计数值,可以在建立的时候确定一个状态数,释放一次计数器
加1,等待函数调用一次减1。特别适合在线程中使用。你看看Delphi的代码,几乎所有涉
及线程同步的地方都是使用Semaphore。
to ifeng:
你的线程同步完全不需要其它的内核对象,只需要线程本身就足够了。
整个过程是这样的:
ThreadA := TThreadA.create(True);
//先挂起,不要运行
ThreadB := TThreadB.Create(False);
//不用担心,线程B会挂起的。
ThreadA.FreeOnTerminate;
//运行结束的时候会释放,释放的时候会发信号
ThreadA.Resume;
//现在正式开始运行线程A
在TThreadB的Execute方法中,必须首先运行:
waitforsingleobject(ThreadA.handle,INFINITE);//线程B在这里卡壳,直到线程A执行完
然后才运行ThreadB应该处理的事。
 
to: barton
高手就是高手!听君一席话,胜编三天程。谢谢您啦。
 
呵呵,barton兄.
这样吧,我问您一个问题.程序结束时Semaphore和mutex的表现有何不同?
如果您能回答得上来,我承认我无知.
这里高手如云,您不必这么动气.
 
这儿有一个我给别人写的例程,
附带一个工具单元
http://new.playicq.com/dispdocnew.php?id=3624
演示线程的同步与互斥,
同时,演示Windows同步对象
临界区的使用,还有动态数组,队列,栈对象的使用
以及线程的安全退出
download
ftp://guest:guestguest@61.129.70.192/datanew/synctest1.rar
 
>>这样吧,我问您一个问题.程序结束时Semaphore和mutex的表现有何不同?
我是菜鸟一个,不敢与你斗气。只是怕有人误人子弟才胡说几句。
semaphore是进程内的对象,进程结束的时候良好的习惯是用closeHandle关闭它,否则会
和文件一样会造成资源泄漏。至于Mutex嘛,因为是进程间对象,所以需要根据应用逻辑
来决定是否释放。如果进程退出,而该进程中的线程拥有对该Mutex的所有权,则会导致
其它等待该Mutex的线程的等待函数返回WAIT_ABANDONED而不是平常的WAIT_OBJECT_0。
偶对线程同步用了N年了,这些东西对偶毫不新鲜。
 
准确的说semaphore在程序崩溃时不会释放,会导致锁死其他的线程!
除此之外mutex基本上可以视为semaphore的一个特例.
barton兄显然对多线程研究极深,那么应该知道semaphore的这个"副作用".
而ifeng又显然刚学线程,如果不把这些说清楚,恐怕以后程序出错时会想破头.
我个人觉得线程这样复杂的东西不适合在网上这样"快餐"式的学习,现在市面上
有一本《win32 多线程程序设计》,候捷老师译的,ifeng兄可去看看。当然
ifeng如果只是应付工作而已,对偶尔程序中的一些非法操作倒也无所谓,那这
些东东也差不多了。
另外“你看看Delphi的代码,几乎所有涉及线程同步的地方都是使用Semaphore。”
我觉得不切事实,barton兄如果完整地统计Semaphore与mutex出现在delphi源码
中的数量,就会发现两者的使用基本差不太多。[我是用工具搜的,也许也不是很准确]
我只是提个醒而已,完整的代码barton兄应该有,我就不多嘴了。
 
好个狡猾的real_clq,自以为聪明。你明明说的是程序结束,什么时候说过程序崩溃?
程序崩溃是一件相当复杂的事情。一旦崩溃你根本无法预料会出现什么结果!如果象你这
么小心翼翼,根本什么事件都不能用,包括Mutex!你只能写单线程的程序了!
设计Mutex这个对象并不是因为Mutex在程序崩溃时比Semaphore有更好的表现,完全是因为
为了实现进程间的同步!
>>我觉得不切事实,barton兄如果完整地统计Semaphore与mutex出现在delphi源码
>>中的数量,就会发现两者的使用基本差不太多。[我是用工具搜的,也许也不是很准确]
实话说大富翁上这样胡搅蛮缠的家伙太多了!完全一个无理取闹!我甚至都没有看到过
Delphi使用Mutex做同步,而Semaphore则遍地用的都是!我见过一本书上讲在程序只能运
行一次的时候用以用Mutex对象,不过不是用来做同步,而是用来检查是否有同一个对象已
经被别的进程建立。
>>我只是提个醒而已,完整的代码barton兄应该有,我就不多嘴了。
你这哪里是提醒,完全是一派胡言。你会把成千上万的初学者引入歧途,你知道吗?
 
barton 啊,你又让我大大受益。 Delphi 5 的源代码里果然除了对 mutex 的定义和建立
外,没有一个地方使用的,真正佩服!
////////////////////// 原文 ////////////////////////
// 来自:ifeng, 时间:2003-7-4 13:42:00, ID:2002812
// to barton
// 看来你对线程挺了解的
////////////////////////////////////////////////////
什么是看来?该好好读读 barton 以前的全部帖子,何止是了解哦?
谢谢 barton 。
 

Similar threads

S
回复
0
查看
3K
SUNSTONE的Delphi笔记
S
S
回复
0
查看
2K
SUNSTONE的Delphi笔记
S
D
回复
0
查看
1K
DelphiTeacher的专栏
D
D
回复
0
查看
1K
DelphiTeacher的专栏
D
后退
顶部