如何访问线程及其组件?

时间:2012-11-27 02:17:20

标签: multithreading delphi thread-safety local-variables delphi-xe3

我创建一个帖子

type 
  ss_thread = class;

  ss_thread = class(TThread)
  protected
    Fff_id : string;
    Fff_cmd : string;
    Fff_host : string;
    Fff_port : TIdPort;
    procedure Execute; override;
  public
    constructor Create(const ff_id, ff_cmd: string; ff_host: string; ff_port: TIdPort);
  end;

constructor ss_thread.Create(const ff_id, ff_cmd: string; ff_host: string; ff_port: TIdPort);
begin
  inherited Create(False);
  Fff_id   := ff_id;
  Fff_cmd  := ff_cmd;
  Fff_host := ff_host;
  Fff_port := ff_port;
end;

...
id := 123;
...

nst_ss_thread.Create(id, cmd, host, port);

并在

上做点什么
procedure ss_thread.Execute;
var
  ws : TIdTCPClient;
  data : TIdBytes;
  i : integer;
  list : TList;
begin
      ws := TIdTCPClient.Create(nil);
      ws.Host := Fff_host;
      ws.Port := Fff_port;
....

如何使用id:= 123 of thread?

通过另一个线程访问此线程'ws'变量

由于

2 个答案:

答案 0 :(得分:3)

它不能。

您已将ws声明为ss_thread.execute内的本地变量,这意味着它只在那里可见。它无法在ss_thread.execute之外看到,即使是ss_thread的其他部分也是如此。

如果您希望从其他地方或线程中看到它,则需要将其移动到更明显的范围。例如,如果您希望从ss_thread中的其他位置显示它,请将其移至privateprotected部分中的界面声明,如果您希望从外部{{1}显示它将其移至ss_threadpublished部分。

答案 1 :(得分:2)

你最好不要。精确地创建线程对象以使其变量与其他线程隔离 否则会出现所有类型的随机不可重现错误 - http://en.wikipedia.org/wiki/Heisenbug

Parallel programming应该有非常清晰的分离和绝缘。因为您永远无法预测执行的时间以及哪个语句将在之前运行,哪个语句将在之后运行。

想象一下简单的场景:

  ws := TIdTCPClient.Create(nil);
  ws.Host := Fff_host;
      // at this point another thread gets access to ws variable, 
      // as You demanded - and changes it, so WS gets another value!
  ws.Port := Fff_port;

如果只在每月一次负载较重的客户端多处理器计算机上发生这样的错误,您会如何检测到这样的错误?在调试会话或模拟期间,您的工作站将无法再现!你会如何抓住它并修复?

根据经验,在进行并行编程时,数据应该是“共享不可变”和“私有可变”部分,并且在进行线程间通信时,您应该 - 类似于进程间通信 - 进行一些事件/ messages队列和pass commands and replies到/来自线程,就像它在Windows GDI中完成一样或在MPI中完成

然后你的线程将从队列中获取“change ws variable”命令 - 在允许更改的适当时刻 - 并从内部更改它。因此,您将采取控制并确保仅在该点更改变量,并且不会使代码流脱轨。

我建议你阅读OTL示例,看看如何以更安全的方式完成线程间通信,直接访问对象。 http://otl.17slon.com/tutorials.htm