paulscherrerinstitute / pcaspy

Portable Channel Access Server in Python
BSD 3-Clause "New" or "Revised" License
33 stars 24 forks source link

How to solve the problem that it publishes an amount of PVs such as more than 2000 PVs by pcaspy? #58

Closed lzxiaohu closed 5 years ago

lzxiaohu commented 5 years ago

Hello, I am a new learner in pcaspy. I try to publish more than 2000 PVs in one python program by pcaspy. However, when the program runs, it would produce the error: CAC: UDP recv error was "WINSOCK Error 10052. So I ask for help. Please help me. default when the same program runs in the other computer, it generates errors: default At last, I put it running in the third computer, it runs normally.

xiaoqiangwang commented 5 years ago

I have used the following program to create 2000 dummy PVs, and seeing no problem. How is your program look like?

caget MTEST:RAND1999 MTEST:RAND1999 0

#!/usr/bin/env python

from pcaspy import Driver, SimpleServer

prefix = 'MTEST:'

class myDriver(Driver):
    def  __init__(self):
        super(myDriver, self).__init__()

if __name__ == '__main__':
    server = SimpleServer()
    pvdb = {}
    for i in range(2000):
        pvdb['RAND%d'%i] = {}
    server.createPV(prefix, pvdb)
    driver = myDriver()

    # process CA transactions
    while True:
        server.process(0.1)
lzxiaohu commented 5 years ago

Thanks for your reply. Yes, your method is ok. In my program, I produce a dictionary of PVs by a function called generate_pv. _def generate_pv(device_type,device_para, device_num): device_series = [str(i) for i in range(1,device_num+1)] pv_property = ['prec', 'scan'] pv_property_value = {'prec': 3, 'scan': 1, 'count': 1, } pv_list = [] result = {} for i in device_series: for j in device_para: pv_list.append(device_type+i+':'+j)

for i in range(len(pv_list)):
    result[pv_list[i]] = {}
for i in pv_list:
    for j in pv_property:
        result[i][j] = pv_property_value[j]
return pv_list, result_

After that, we call the function in the main function by _pv_list, pvdb1 = generate_pv(device_type, device_para, devicenum) server.createPV(prefix, pvdb1) The method can run correctly in some computers. However, it produce errors described above in some computers. I don't understand why the phenomenon happen. Can you help me? looking forward to your reply!

xiaoqiangwang commented 5 years ago

The problem is that all PVs are using 'scan': 1. Because the scan thread is individual to each PV, this requires 2000 threads, which might exceed the system limits.(I don't have the exact number though.)

It is suggested to use your own updating thread to update PV values in batch. See the tutorial, and the final remark.

lzxiaohu commented 5 years ago

I got it. However, I don't how to update PV values in batch. Now I am sure that PV values continue to changing through caget, while the command camonitor cannot monitor the changes of PV values. Can you explain in detail that how to update PV values in batch. Thanks!

xiaoqiangwang commented 5 years ago

At the end of calling self.setParam, add a call to updatePVs. e.g.

    # set PVs new values
    self.setParam('RAND1', 0.1)
    self.setParam('RAND2', 0.2)
    ...
    # update PVs new values to registered clients
    self.updatePVs()
lzxiaohu commented 5 years ago

Thank you for you precious advice. According to your suggestion, I have solved my problem.