【如何开启多线程】
要启动一个新线程,用par_start限定符作为相应操作符或过程调用的前缀:'
- par_start <ThreadID> : gather_data()
- ...
复制代码
该调用将基于函数gather_data()作为一个在后台运行的新的子线程并且执行后续的程序行。这个线程标识的变量以ThreadID进行返回。和在HDevelop不一样的是,在HDevEngine中仅在启动线程的函数中给出的ThreadID才是有效的。
注意,par_start不是一个实际的操作符,而是一个修改调用形为的限定符,因此,不能在算子窗口取选择它!
如果启动一个新的子线程将超过系统配置的最大线程数,将会引发异常抛出!
你也可以一个函数或算子调用开始子线程,通过下面的算子窗口:
如果要开启子线程,需要开启下方的“高级并行选项”并勾选复选框:
它支持在一个循环中启动多个线程。在这种情况下,需要收集线程标识,以便以后可以引用所有线程:
- ThreadIDs := []
- for Index := 1 to 5 by 1
- par_start <ThreadID> : gather_data()
- ThreadIDs := [ThreadIDs, ThreadID]
- endfor
复制代码
同时,我们可以在向量变量中收集这些线程标识将会非常有用:
- for Index := 1 to 5 by 1
- par_start <ThreadIDs.at(Index - 1)> : gather_data()
- endfor
复制代码
当子线程返回输出变量中的数据时,必须特别小心。特别是,当子线程仍在运行时,不能在其他线程中访问输出变量。否则,数据不保证有效。
同样,必须确保多线程不会干扰它们的结果。假设过程gather_data以如上所示的多个线程启动,但在输出控制变量中返回数据:
for Index := 1 to 5 by 1
par_start <ThreadIDs.at(Index - 1)> : gather_data(Result) // BEWARE!!!
endfor
在上面的例子中,所有的线程都会在同一个变量中返回它们的结果,这肯定不是我们想要的。结果的最终值将是最后完成的线程的(不可预测的)返回值,所有其他结果都将丢失。
这个问题的一个简单解决方案是收集向量变量中的返回数据,如前面的线程标识所示:
- for Index := 1 to 5 by 1
- par_start <ThreadIDs.at(Index - 1)> : gather_data(Result.at(Index - 1))
- endfor
复制代码
这里,每次调用收集数据都会在向量变量result的一个唯一槽中返回结果。
|