多线程同步:互斥量使用

问题:200分,多个线程把搜集的数据各自生成txt文件,只启动一个线程添加到数据库,请指教?

http://www.delphibbs.com/delphibbs/dispq.asp?lid=1233274

来自:yecloudy, 时间:2002-7-31 9:16:00, ID:1233274 [显示:小字体 | 大字体] 

200分,多个线程把搜集的数据各自生成txt文件,只启动一个线程添加到数据库,请指教?
实现目的:
    通过多线程把多个串口的数据添加到数据库。
实现模型:
    1、启用多个线程(比如说a,b,c,d).
    2、a,b,c,d各自搜集数据。把搜集的数据各自添加到对应的txt文件。(a.txt,b.txt,c.txt,d.txt)
    3、假使a搜集完成,通知另一个线程e,e就把a.txt文件添加到数据库。
    4、同时,假如b也搜集完成,通知e,要等e添加a.txt完后,再来添加b.txt.
请问:
    1。e线程要怎么写。
    2。线程a,b如何通知e,sendmessage只能用于window,有没有能通知启用线程的。
    3。为了数据库不冲突,e同一个时刻只能添加某个文件的数据,所以怎么让b必须等到e在添加完a.txt再添加b.txt.(a.txt,b.txt不是特定的,谁先搜集完数据,就先。)  

来自:zhliangming, 时间:2002-7-31 9:29:00, ID:1233342
我觉得可以借助主线程。在主线程中维护一个列表。当a、b、c搜集完数据时就往该列表中插数据。
而e就轮询该列表,一组一组地处理数据。另外也可以考虑在主线程中完成e的功能啊。 

来自:HeyTommy, 时间:2002-8-4 10:23:00, ID:1241538
可以不要e线程的,但你需要在那几个线程中进行同步!
我在http://www.delphibbs.com/delphibbs/dispq.asp?lid=1237936
说明了如何用的方法,哎呀,我在这里顺便给你粘过来好了!
1、你先要在创建任何线程前定义并创建一个全局的互斥对象:
var  hMutex:THandle;
在程序的初始化部分创建该对象(在FormCreate或Initialization里都可以)
hMutex:=CreateMutex(nil,false,nil);
2、然后在你的线程体中将你需要保护的地方使用如下代码:
if WaitForSingleObject(hMutex,INFINITE)=WAIT_OBJECT_0 then
  begin
    //在此处添加你需要对数据库进行操作的代码
  end;
//释放互斥对象,使其为发信号状态
ReleaseMutex(hMutex);

3、注意,别忘了在你的应用程序终止前用CloseHandle(hMutex)来删除该互斥对象,不然它将
在系统中一直存在(它是系统全局的对象);

这样,你就不怕你的多个线程冲突或出现“死锁”了:)
如果你给出代码,我也可以给你一个实际例子的,呵呵:) 

来自:HeyTommy, 时间:2002-8-4 18:38:00, ID:1242226
1:临界区和互斥的作用类似,都是用来进行同步的,但它们间有以下一点差别:
  临界区只能在进程内使用,也就是说只能是进程内的线程间的同步;而互斥则还可用
  在进程之间的;临界区所花消的时间很少,才10~15个时间片,而互斥需要400多个;
  临界区随着进程的终止而终止,而互斥,如果你不用closehandle()的话,在进程
  终止后仍然在系统内存在,也就是说它是系统全局对象;
2:当a在进行数据库的操作时,如果别的线程完成了采数,那么,它必须等到同步对象变
  为发信号状态,也就是说要等a把工作作完了才能往数据库中加数据;
不知道这样的回答你还满意不? 


请问用Mutex来做线程同步啊!怎么做啊???

哎呀,给个例子给你!列出的是部分代码,包含关键部分,下面的与完整的差不了多少了!
type
TMainForm=class(TForm)
Button1:TButton;
ListBox1:TListBox;
procedure Button1Click(Sender:TObject);
private
procedure ThreadDone(Sender:TObject);
end;

TMyThread=class(TThread)
protected
procedure Execute;override;
end;

var
MainForm:TMainForm;
DoneNum:integer; 
hMutex:THandle=0;

//线程体
procedure TMyThread.Execute;
var
  i:integer;
begin
FreeOnTerminate:=true;
OnTerminate:=MainForm.ThreadDone;
if WaitForSingleObject(hMutex,INFINITE)=WAIT_OBJECT_0 then
  begin
  for i:=1 to 100 do
    Sleep(5);
  end;
//释放互斥
ReleaseMutex(hMutex);
end;

procedure TMainForm.ThreadDone(Sender:TObject);
var
  i:integer;
begin
Inc(DoneNum);
if DoneNum=2 then
begin
for i:=1 to 100 do
  ListBox1.Items.Add(IntToStr(i));
//关闭互斥句柄
CloseHandle(hMutex);
end;
end;

procedure TMainForm.Button1Click(Sender:TObject);
begin
//创建互斥
hMutex:=CreateMutex(nil,false,nil);
TMyThread.Create(false);
//创建线程
TMyThread.Create(false);
end; 

来自:HeyTommy, 时间:2002-8-4 0:28:00, ID:1241303
把代码粘上来后发现少了点注释,现在加上:

在这个例子中,比较关键的是用WaitForSingleObject来防止另外一个线程进入同步区的代码,
也就是说这个函数要一直等到hMutex变成发信号态,下面的同步代码才被执行! 

原文地址:https://www.cnblogs.com/railgunman/p/1870867.html