主线程如何接收子线程执行的返回值(消息) ( 积分: 20 )

  • 主题发起人 主题发起人 chenxp3000
  • 开始时间 开始时间
C

chenxp3000

Unregistered / Unconfirmed
GUEST, unregistred user!
比如说:我在一个方法(SaveBillData)里面需要创建了3个线程用来更新数据库,它们分别对应三个数据表(tb_a,tb_b,tb_c),每个线程中调用了同一个方法updateDatapack(),该方法有一个返回值说明更新数据表是否成功,例如:Ret :=updateDatapack() ,if Ret='0' then
成功,else
失败!由于需要保证事物,所以判断保存是否成功需要同时知道三个线程的返回值才能确定,请问如何把这个三个线程的执行结果(Ret)返给saveBillData呢?然后再由(SaveBillData)决定需要commit还是rollback.希望能说得具体一些。
备注:Synchronize方法我用了,但是该方法是用来同步线程根VCL的,我希望在调用(SaveBillData)时,三个线程A,B,C执行结束完能把Ret返给(SaveBillData)然后(SaveBillData)再接着往下处理。现在问题是等三个线程执行完以时,方法(SaveBillData)也早就执行完了。用什么方法能让(SaveBillData)挂起,等三线程执行完后(SaveBillData)再继续。谢谢
 
比如说:我在一个方法(SaveBillData)里面需要创建了3个线程用来更新数据库,它们分别对应三个数据表(tb_a,tb_b,tb_c),每个线程中调用了同一个方法updateDatapack(),该方法有一个返回值说明更新数据表是否成功,例如:Ret :=updateDatapack() ,if Ret='0' then
成功,else
失败!由于需要保证事物,所以判断保存是否成功需要同时知道三个线程的返回值才能确定,请问如何把这个三个线程的执行结果(Ret)返给saveBillData呢?然后再由(SaveBillData)决定需要commit还是rollback.希望能说得具体一些。
备注:Synchronize方法我用了,但是该方法是用来同步线程根VCL的,我希望在调用(SaveBillData)时,三个线程A,B,C执行结束完能把Ret返给(SaveBillData)然后(SaveBillData)再接着往下处理。现在问题是等三个线程执行完以时,方法(SaveBillData)也早就执行完了。用什么方法能让(SaveBillData)挂起,等三线程执行完后(SaveBillData)再继续。谢谢
 
自己写一个procedure terminateNotify;在其中写一些通知事件
设置子线程的FreeOnTerminate :=False
同时设定子线程的OnTermiate :=terminateNotify;
然后再Resume子线程
 
定义一个全局变量
初始值为子线程数量
一个子线程工作完了就减一
 
WaitForMultipleObjects
 
写三个function,每个都不一样;不同线程调用不同function;
不知道行不行;
 
to dawnsong:
你好,你这个方法应该可以,但是的话,这几个线程成了逻辑上的"串行"执行了!跟使用单线程好象没什么大的区别(我使用三个线程是希望并行同时储存三个表).
 
这几个线程成了逻辑上的"串行"执行了
-----------------------------------
这怎么会呢。不知道楼主手边有没有C++Builder6,其中有个三线程三种方法排序的Demo,其使用的就是这种方法,你可以参考一下,那个代码写的很精炼;不过我手边没有,无法贴上来,很遗憾
写了一个terminateNotify后,三个线程其各自结束的时候,都会调用这个主程序中的这个事件,但这仅限于结束的时候,这时候因为是在主线程中执行程序,所以也不必做些内存保护的动作,这应该说是Borland很精巧的设计
 
WaitForMultipleObjects 是用来同步各子线程的(包括临界区、互斥、信号、事件等),
我现在需要的子线程和主线程同步的问题,也就是说各个子线程执行完以后需要把结果返回各主线程,然后主线程再做一些处理,在各个子线程还没有执行完成时,主线程sleep(sometime)等待。
 
to dawnsong:谢谢你!
不好意思,刚才看错了!你的方法确实可以,但是现在又有一问题,子线程还没有执行完返回时,方法SaveBillData已经执行完毕了,这是即使子线程返回了值,SaveBillData方法也无法根据返回值作相应的处理。有什么好的方法可以使SaveBillData挂起,等各子线程都执行完毕后再唤醒SaveBillData继续执行!谢谢
 
{
我看了一下Delphi9,其Demo里也有如上我所说的那个3线程3方法排序的Demo,楼主参考一下其是如何同步的,就是靠ThreadDone
}
uses SortThds;
{$R *.dfm}
type
PSortArray = ^TSortArray;
TSortArray = array[0..114] of Integer;
var
ArraysRandom: Boolean;
BubbleSortArray, SelectionSortArray, QuickSortArray: TSortArray;
{ TThreadSortForm }
procedure TThreadSortForm.PaintArray(Box: TPaintBox;
const A: array of Integer);
var
I: Integer;
begin
with Boxdo
begin
Canvas.Pen.Color := clRed;
for I := Low(A) to High(A)do
PaintLine(Canvas, I, A);
end;
end;

procedure TThreadSortForm.BubbleSortBoxPaint(Sender: TObject);
begin
PaintArray(BubbleSortBox, BubbleSortArray);
end;

procedure TThreadSortForm.SelectionSortBoxPaint(Sender: TObject);
begin
PaintArray(SelectionSortBox, SelectionSortArray);
end;

procedure TThreadSortForm.QuickSortBoxPaint(Sender: TObject);
begin
PaintArray(QuickSortBox, QuickSortArray);
end;

procedure TThreadSortForm.FormCreate(Sender: TObject);
begin
RandomizeArrays;
end;

procedure TThreadSortForm.StartBtnClick(Sender: TObject);
begin
RandomizeArrays;
ThreadsRunning := 3;
with TBubbleSort.Create(BubbleSortBox, BubbleSortArray)do
OnTerminate := ThreadDone;
with TSelectionSort.Create(SelectionSortBox, SelectionSortArray)do
OnTerminate := ThreadDone;
with TQuickSort.Create(QuickSortBox, QuickSortArray)do
OnTerminate := ThreadDone;
StartBtn.Enabled := False;
end;

procedure TThreadSortForm.RandomizeArrays;
var
I: Integer;
begin
if not ArraysRandom then
begin
Randomize;
for I := Low(BubbleSortArray) to High(BubbleSortArray)do
BubbleSortArray := Random(170);
SelectionSortArray := BubbleSortArray;
QuickSortArray := BubbleSortArray;
ArraysRandom := True;
Repaint;
end;
end;

procedure TThreadSortForm.ThreadDone(Sender: TObject);
begin
Dec(ThreadsRunning);
if ThreadsRunning = 0 then
begin
StartBtn.Enabled := True;
ArraysRandom := False;
end;
end;
 
再唤醒SaveBillData继续执行
--------------------------
我感觉没必要,呵呵,程序结构不必要这么复杂化,你看一下那个Demo,应该就会了解很多
 
to dawnsong,: 谢谢!你贴出来的代码我看了,但因为我使用子线程来分别更新数据表,其中的子线程更新数据表有可能失败,如果有失败的,方法SaveBillData需要以某种形式告诉用户,当然了,这里还涉及到事务完整性的问题。我不知道我说明白了没有!
 
呵呵,明白楼主的意思,楼主就是想让SaveBillData来等待一下,
我以前是这么解决处理这个问题的:
主线程中定义一个回调函数,每个子线程结束的时候,Synchronize这个回调函数,呵呵,这个方法不比等待复杂吧,而且可以处理很多事情,包括楼主所说的判定执行成功否,你甚至可以把这个回滚操作都放到这个回调函数里面:)
 
呵呵!谢谢,我明白了!
但是好像还有个问题,如果用三个线程A,B,C 分别更新tb_A,tb_B,tb_C,现在有个问题就是如果B线程更新失败了,A,C都更新成功了,怎样回滚线程A,C更新过的表tb_A,tb_C的内容,好像主线程中的事务回滚没办法回滚子线程中的事务。dawnsong有没有什么办法可以实现着用的功能。非常感谢!
 
呵呵,越说越多了:)
怎么回滚我可不知道,你是否认为只定义一个回调函数,用它来判断并回滚三个表的内容?呵呵,恐怕难做,除非三个表由极大的相似性,三个线程的操作也有极大的相似性
你可以这么来:
threadA.OnTermiate :=terminateNotifyA;
threadB.OnTermiate :=terminateNotifyB;
threadC.OnTermiate :=terminateNotifyC;
 
谢谢你!我是放在三个回调事件中处理,但是跨线程回滚事务好像不行呀·
哎!郁闷。呵呵。
 
谢谢大家!在这里要特别感谢dawnsong,我的问题解决了!现在开始发分!~!
 
多人接受答案了。
 
后退
顶部