zoukankan      html  css  js  c++  java
  • 多线程同步:互斥量使用

    问题: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变成发信号态,下面的同步代码才被执行! 

  • 相关阅读:
    浅谈java中异常处理
    Android四大组件之BroadcastReceiver
    android基本组件 Button
    Android基本组件TextView和EditView
    Unicode,GBK和UTF8
    记一次生产上的紧急修复之后解疑过程
    使用第三方jar时出现的问题
    码农歌单
    创建servlet程序知识点详解---servlet-day12
    创建servlet程序知识点详解---servlet-day07
  • 原文地址:https://www.cnblogs.com/railgunman/p/1870867.html
Copyright © 2011-2022 走看看