学习open62541 --- [78] 单线程和多线程的使用场景

open62541提供多线程功能,默认不开启,即单线程,
在这里插入图片描述
把UA_MULTITHREADING的值设置为 >= 100就可以开启多线程了。

这里单线程/多线程的意思是基于open62541运行的server内部是否使用锁去保护数据。只要server运行后还有读写操作需要做,那么就要考虑这些情况。

但是何时使用多线程,何时使用单线程呢?本文讨论他们的不同使用场景。


一 单线程使用场景

默认是单线程,也就是当有多个线程去读写server里的变量时,open62541内部不提供数据访问的保护,这种情况下容易造成未知情况。

例如server某个节点添加了监测项,查询周期50ms,当该变量值有变化就会去执行对应的回调,主线程运行UA_Server_run(),然后额外开一个线程去写这个变量。这样很有可能遇到读取的变量值是个比较诡异的值,因为server内部对变量没有加锁来保护。

本人亲测:写变量一直使用相同的值写,这样也会触发监测回调,然后回调里打印的值是个怪异值。

那么什么时候使用单线程呢?经过以上分析可知,读写变量的操作必须和UA_Server_run()处于一个线程,可能会问:UA_Server_run()是阻塞的,那还如何去做读写操作呢?

open62541提供了执行定时任务的api,可以参考这篇文章。通过定时任务的api来添加读写操作,添加好之后,会在UA_Server_run()里定时去做这些操作,这样就不会出现并行访问数据的情况了。

对于Client端发送的读写请求,由于这些请求是由UA_Server_run()来处理,所以也不会出现问题。


二 多线程使用场景

开启多线程之后,open62541内部使用锁来保护数据的访问,这样在server端用户可以额外开线程去读写server里的变量。

这里以UA_Server_writeValue举例,其定义如下
学习open62541 --- [78] 单线程和多线程的使用场景_第1张图片
而__UA_Server_write的定义如下,
学习open62541 --- [78] 单线程和多线程的使用场景_第2张图片
当UA_MULTITHREADING>=100时,UA_LOCK和UA_UNLOCK定义如下,
学习open62541 --- [78] 单线程和多线程的使用场景_第3张图片
当然,如果UA_MULTITHREADING为0~99时,他们的定义为空,如下,
学习open62541 --- [78] 单线程和多线程的使用场景_第4张图片


三 小结

本文讲述了open62541的单线程和多线程的使用场景,可以根据需要决定是否开启多线程。

你可能感兴趣的:(open62541,学习,服务器)