两个线程如何实现串行执行?(50分)

  • 主题发起人 主题发起人 shangrand
  • 开始时间 开始时间
S

shangrand

Unregistered / Unconfirmed
GUEST, unregistred user!
3个线程,
T1.create
T2.create
T3.create
如何实现T2在T1完成后再执行?
 
其实就是线程同步问题,可能用API
WaitForSingleObject
实现你想要的功能。
 
设定一个全局变量,根据变量的状态运行
 
同步的方法有很多中,最直接的就是"临界区":依次只能由一个线程来执行的一段代码,另一个线程在第一个线程处理完之前是不会被执行的.
在使用临界区之前必须要初始化:InitializeCriticalSection
网上这样的成熟代码很多,你搜索一下吧.
其实你这样的情况使用同步基本上是不搭界的,你必须建立一个TStringList变量,一旦创建表时,该变量被赋值为这些表名的串SLA;执行SQL语句的线程的SQL语句应该来自于队列,该队列至少由相关的表名和SQL语句组成,执行的前提就是,该相关的表名中不能包含SLA的内容
 
前两位说的都正确
查一下Windows内核同步对象就明白了
 
楼主要的好像不是同步
 
补充:我现在问题如下:
T1创建表A
T2往表A填写数据
T3,T4,T5,T6并发访问表A(只是select,没有update和delete)
T1,T2,(T3,T4,T5,T6)是不是串行执行?现在一定用线程。好像和"临界区","互斥量"等有一点区别,他们的是"一段代码",我的是服务器上的数据。
 
设定两个变量,根据变量的状态运行
x 为线程变量
y 为公共变量
t1:=thread.create;
t1.x:=1
t2:=thread.create;
t2.x:=2
t3:=thread.create;
t3.x:=3
.............
y:=1;
while truedo
begin
if x<>y then
continue
...
线程要结束时
inc(y);
end;
 
其实就是线程同步问题,可以用API
WaitForSingleObject
实现你想要的功能。
具体查看MSDN,很简单易明。
 
给你刚弄的一个例子:
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, ExtCtrls;
type
TForm1 = class(TForm)
ListBox1: TListBox;
Button1: TButton;
procedure Button1Click(Sender: TObject);
procedure FormCreate(Sender: TObject);
procedure FormDestroy(Sender: TObject);
procedure Timer1Timer(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;

var
Form1: TForm1;
hMutex: THandle = 0;
//定义
implementation
uses unit2;
{$R *.dfm}
procedure TForm1.Button1Click(Sender: TObject);
begin
listbox1.Items.Clear;
ThreadT1.create(100, 'A');
ThreadT1.create(100, 'B');
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
hMutex := CreateMutex(nil, False, nil);
//创建
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
CloseHandle(hMutex);
//释放
end;
end.

------
unit Unit2;
interface
uses
Classes, SysUtils, Windows, unit1;
type
ThreadT1 = class(TThread)
private
FiMax: integer;
Foption: string;
Fi: integer;
{ Private declarations }
protected
procedure Execute;
override;
procedure AddItem();
public
constructor create(iMax: integer;
option: string);
end;

implementation
{ ThreadT1 }
procedure ThreadT1.AddItem;
begin
inc(Fi);
Form1.ListBox1.Items.Add(format('item%s %d', [Foption, Fi]));
end;

constructor ThreadT1.create(iMax: integer;
option: string);
begin
FiMax := iMax;
Foption := option;
FreeOnTerminate := true;
inherited create(false);
end;

procedure ThreadT1.Execute;
var
i: integer;
begin
if WaitForSingleObject(hMutex, INFINITE) = WAIT_OBJECT_0 then
//WAIT_OBJECT_0 指定的对象处于发信号状态;
for i := 0 to fimax - 1do
// 调用WaitForSingleObject()函数的线程就成为该互斥对象的拥有者,此互斥对象设为不发信号状态。
begin
sleep(50);
Synchronize(AddItem)
end;
ReleaseMutex(hMutex);
//复位 重新进入发信号状态
end;

end.
 
同步的方法有很多中,最直接的就是&quot;临界区&quot;:依次只能由一个线程来执行的一段代码,另一个线程在第一个线程处理完之前是不会被执行的.
在使用临界区之前必须要初始化:InitializeCriticalSection
网上这样的成熟代码很多,你搜索一下吧.
其实你这样的情况使用同步基本上是不搭界的,你必须建立一个TStringList变量,一旦创建表时,该变量被赋值为这些表名的串SLA;执行SQL语句的线程的SQL语句应该来自于队列,该队列至少由相关的表名和SQL语句组成,执行的前提就是,该相关的表名中不能包含SLA的内容
 
后退
顶部