0

我创建一个线程

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' 变量?

谢谢

4

2 回答 2

3

这不可以。

您已ws在内部声明为局部变量ss_thread.execute,这意味着它仅在此处可见。外面看不到ss_thread.execute,其他地方也看不到ss_thread

如果您希望它从其他地方或线程可见,则需要将其移动到更可见的范围。例如,如果您希望它从 中的其他地方可见,请将其移动到或部分ss_thread中的接口声明,如果您希望它从外部可见,请将其移动到或部分。privateprotectedss_threadpublishedpublic

于 2012-11-27T03:47:52.603 回答
2

你最好不要。线程对象正是为了将其变量与其他线程隔离开来。
否则会出现各种随机不可重现的错误 - http://en.wikipedia.org/wiki/Heisenbug

并行编程应该有非常明确的分离和绝缘。因为您永远无法预测执行的时间以及哪个语句会更早运行以及哪个语句会更晚运行。

想象一下这个简单的场景:

  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;

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

根据经验,在进行并行编程时,数据应该被分成“共享不可变”和“私有可变”部分,并且在进行线程间通信时,你应该 - 类似于进程间通信 - 使一些事件/消息排队向/从线程传递命令和回复,就像在 Windows GDI 中或在 MPI 中一样

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

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

于 2012-11-27T08:09:43.590 回答