Delphi OmniThreadLibrary + OPC客户端

Igo*_*rMF 3 delphi multithreading opc

我正在一个单线程OPC客户端程序中工作,该程序管理连接到同一OPC服务器的3个不同的西门子PLC,也是西门子的.

单线程客户端看起来像这样:

loop
 begin
  processPLC1;
  processPLC2;
  processPLC3;
end;
Run Code Online (Sandbox Code Playgroud)

每个processPLC过程都会调用底层OPC库,例如:

 OPCutils.WriteOPCGroupItemValue(FGroupIf, FHandleItemOpc, Value);
Run Code Online (Sandbox Code Playgroud)

好的,现在我想在不同的线程中调用每个processPLC并且并行工作.

我做了一些研究,并使用OmniThreadLibrary开始了一些代码,但我不认为OPC代码是多线程安全的.是吗?

我应该使用task.Invoke或类似的东西吗?ReadOPC函数怎么样,返回PLC标签的值?这里最好的做法是什么?

谢谢!!!

J..*_*... 5

我一般认为这有两个方面:

1)应用程序具有单个线程拥有的单个OPC客户端实例.然后,客户端应用程序自动执行的所有并行进程在读取/写入OPC值时使用某种消息传递或与拥有OPC客户端的线程同步.

2)每个线程拥有自己的专用OPC客户端,每个客户端都与OPC服务器独立通信.

就个人而言,我发现最常用的方案是前者; 一个OPC(或其他专有)客户端对象,其中线程对客户端进行同步调用.实际上,在几乎所有过程控制情况下,您都是多线程的,目的是优雅地封装逻辑真实世界任务并将其与UI分离,而不是任何类型的性能.这些线程可以在相对"长"的时间段内阻塞等待数据 - 如果需要,PLC将很乐意将堡垒压住一百毫秒.

您选择哪一个在很大程度上取决于您的应用程序的规模和性质.对于许多花费很长时间等待外部实时事件的轻量级线程,在应用程序中保留单个OPC客户端实例并节省大量独立连接的开销是有意义的.对于少量繁重,快速移动的OPC密集型线程,可能有必要为每个线程提供自己的OPC客户端.

还要记住OPC标签的刷新率 - 很多时候服务器只在大约100ms左右的时间内更新它们.它可能只需要你的PLC至少10毫秒即可执行单次扫描.当数据永远不会快速刷新时,让大量线程每秒独立轮询服务器一百次是没有意义的.

对于过程控制软件,您真正想要的是拥有大量空闲或低负载的CPU时间 - 线程越轻越好.总体系统响应能力是关键,并且能够让您的软件处理高负载情况(突然大量任务收敛,而操作系统决定是时候索引硬盘驱动器......净空可以保持齿轮润滑,可以这么说).你的大多数线程可能只是在大部分时间等待.事件和回调通常在这里最有意义.

此外,考虑PLC编程也很重要.例如,在我的机器中,我有一些非常时间关键的操作,同时,每次运行时都是唯一的时间 - 这些是持续时间为几分钟的过程,时间不到十分之一一秒或更好,每天重复数百至数千次,并且每次运行时都具有关键但不同的持续时间.我已经看到过这两种方式 - 一种是软件,一种是PLC.对于前一种情况,软件告诉PLC何时启动,然后直到软件告知它停止.这有明显的陷阱; 在这种情况下,只需将时间间隔发送到PLC并让它进行计时就好了.突然间,所有时间/轮询压力都从软件中消失,并且该过程可以优雅地处理自动化计算机崩溃等事情.如果您想要对OPC服务器施加重大压力以获取对时间要求严格的数据,通常需要支付重新评估整个系统的设计 - 软件和PLC.