Версия, подходяща за принтиране
Кликни тук, за да видиш темата в оригиналният и вид
BG Development Форуми > PHP/Perl/Python/ASP > Python threading


Публикувано от: dedal 21-06-2018, 18:27
Софтуера е доста сложен и и голя и ще се постарая да обясня накратко.

Идеята е следна.
имаме файл demon.py
неговата работа е да синхронизира часовника и да вдигне всички трейдове.
Всички трейдове имат event и стоят в режим .wait()
освен 3:
1. синхронизация с база данни
2. диагностика ( измерва температура, волтаж и ампераж, като и дали всички други трейдове са активни)
3. UDP сървър който се явява последен и основен трейд
ИЛИ ИЗГЛЕЖДА ТАКА:
CODE

   jp_q_clena = threading.Thread(target=jp_proc.q_clean)
   jp_q_clena.setDaemon(True)
   jp_q_clena.start()

   jp_server = threading.Thread(target=jp_proc.jp_server)
   jp_server.setDaemon(True)
   jp_server.start()

   rfid_proc = threading.Thread(target=rfid_proc.rfid_proc)
   rfid_proc.setDaemon(True)
   rfid_proc.start()

   ks_proc = threading.Thread(target=ks_proc.ks_proc)
   ks_proc.setDaemon(True)
   ks_proc.start()

   bonus_proc = threading.Thread(target=bonus_cart_proc.bonus_proc)
   bonus_proc.setDaemon(True)
   bonus_proc.start()

   ks = MEM_DB.get_key('ks')
   if ks['work'] == True:
       libs.log.stdout_sys.info('KS PROK SET: ks_work=%s' % (ks['work']))
       libs.sysobj.KS_WORK_EVT.set()
       libs.sysobj.RFID_WORK_EVT.set()
   libs.udp.run_server()


Ако стартирам demon.py всичко работи. Процесите се стартират и няма проблеми.
В момента се стартират около 10 трейда, в зависимост от лиценза.

И тук идва проблема:
demon.py е компилиран до C и от там с gcc до demon.so
За да се стартира има стартираш файл main.py който има само един ред
CODE

   import demon

По този начин трейдовете не работят правилно
ако в main.py
поставвя
CODE

   import demon
   demon.libs.udp.run_server() # премахвам от демона libs.udp.run_server()

Така всичко работи. Не мога да схвана логиката. Изчетох цялата документация и не намерих нищо.
А самата функция на UDP сървъра изглежда така:
CODE

   def run_server(port=sysobj.UDP_PORT, *args):
       log.stdout_udp.info('SERVER PROC STARTING!')
       address = ('', port)
       if sysobj.UDP_IN_THREAD == True:
           server = ThreadedUDPServer(address, EchoRequestHandler)
       else:
           server = SocketServer.UDPServer(address, EchoRequestHandler)
       server.allow_reuse_address = True
       server.allow_reuse = True
       t = threading.Thread(target=server.serve_forever())
       t.setDaemon(True)
       t.start()


Някой има ли представа защо се получава този феномен ?

Публикувано от: bvbfan 21-06-2018, 18:45
За да се извика трябва да бъде експортирана функция от .so т.е. след import трябва да се извика функция, как се прави .so-то?

Публикувано от: dedal 21-06-2018, 19:08
QUOTE (bvbfan @ 21-06-2018, 18:45)
За да се извика трябва да бъде експортирана функция от .so т.е. след import трябва да се извика функция, как се прави .so-то?

.so се прави така
CODE

   cython demon.py -o demon.c
   gcc -shared -pthread -fPIC -fwrapv  -Wall -fno-strict-aliasing -I/usr/include/python2.7 -o demon.so demon.c


Не е в импорта тъй като самия demon.py играе ролята на стартиращ скрипт и няма функции.

А и преди компилиране до .so пак отказва да работи
или ако подам
python demon.py
работи, но при
python main.py
всички трейдове сратират показват в лога, че тръгват но спират.
Или има трейд (bonus) който получава информация от rfid трейда. В зависимот от поставената карта подава сигнал към серийния трейд който от своя страна прави нещо и връща True

След Получаване на True. Bonus трейда трябва да направи запис в централна база.
Но не прави запипс.

Опитвам конекция преди стартиране на трейда и не се канектва ако не преместя udp трейда в main.py


CODE

   def bonus_proc():
       libs.log.stdout_bonus_cart.info('PROC STARTING!')
       MEM_DB = libs.sysobj.MEM_DB
       postgreDB = libs.db.PostgreSQL(host=libs.sysobj.DB_SYS_HOST,
                                  user='user', passwd='pass',
                                  dbname='db_name',
                                  port=libs.sysobj.DB_SYS_PORT)
       while True:
           bonus_id = libs.sysobj.BONUS_Q.get()
           libs.sysobj.BONUS_SAS_REQUEST.put(['sas.set_bonus', {'mony':all_bonus[bonus_id]['mony'], 'tax':'00' }])
           data = libs.sysobj.BONU_SAS_RESPONSE.get(timeout=(libs.sysobj.TIMEOUT))
          if data == True:
               postgreDB.connect() # Тук процеза зависва


В началото помислих, че липсва връзка
опитах така

CODE

    def bonus_proc():
       libs.log.stdout_bonus_cart.info('PROC STARTING!')
       MEM_DB = libs.sysobj.MEM_DB
       postgreDB = libs.db.PostgreSQL(host=libs.sysobj.DB_SYS_HOST,
                                  user='user', passwd='pass',
                                  dbname='db_name',
                                  port=libs.sysobj.DB_SYS_PORT)
       postgreDB.connect() # Зависва тук, но ако се пусне udp през main.py тук минава нормално
       bonus_id = postgreDB.get("SELECT id FROM bonus_cart WHERE cart='%s';"  % ('F2F5A34A'))[0]
       postgreDB.close()
        print bonus_id
       while True:
           # Направи нещо

Публикувано от: bvbfan 21-06-2018, 20:03
Според мен, как аз съм правил това,

CODE
def main_func():
   #тук идва цялата логика

main_func()

#това е py-то

import daemon
daemon.main_func()


Функцията трябва да се експортне, за да се вижда или даваш --export-all-symbols на линкера. Що се отнасе до постгре-то е доста специфично дали си намира модулите за него. Пусни го в козола да видиш плюе ли грешки.

Публикувано от: Gamma Goblin 21-06-2018, 20:17
Ако ползваше джава нямаше да имаш такива проблеми icon_smile.gif

Публикувано от: bvbfan 21-06-2018, 20:31
Python е език от по-високо ниво, като цяло дори няма смисъл от гимнастиките, които правят. А ги правят за бързодействие, което се постига с pypy. Интерфейсът със C за съвместимост с вече написан софтуер.

Публикувано от: dedal 06-07-2018, 12:12
QUOTE (Gamma Goblin @ 21-06-2018, 20:17)
Ако ползваше джава нямаше да имаш такива проблеми icon_smile.gif

Да на java нямаше да имам проблем с трейдовете който е лесно разрешим.
Просто основния трейд трябва да се извика в стартиращия файл.
На java проблема щеше да е, че вместо 10 000 реда, трябваше да напиша 50 000 и то ако имам късмет.

Програмата е доста сложна.
Или 50 различни устройства обединяват, процесор, кеш, рам, хард и се синхронизират.
Като на всяко устройство има демон на заден фон и графика която се вдига като самостоятелна програма.
Или на всяко устройство имам по 40 трейда в 2 различни програми. Като всяко говори със трейдовете на останалите 50 компютъра.

Въпросът беше за python със C++ extention. Хайде да не се съветваме на какво трябва да пиша, а да си отговаряме по темата.

Публикувано от: Gamma Goblin 06-07-2018, 12:19
QUOTE
Хайде да не се съветваме на какво трябва да пиша, а да си отговаряме по темата.


Добре. В такъв случай, трябва да ти кажа, че "трейд -> trade" означава търговия.

Публикувано от: dedal 06-07-2018, 12:20
QUOTE (bvbfan @ 21-06-2018, 20:03)
Според мен, как аз съм правил това,

CODE
def main_func():
   #тук идва цялата логика

main_func()

#това е py-то

import daemon
daemon.main_func()


Функцията трябва да се експортне, за да се вижда или даваш --export-all-symbols на линкера. Що се отнасе до постгре-то е доста специфично дали си намира модулите за него. Пусни го в козола да видиш плюе ли грешки.

Грешки няма.
Същото се случва и с wx
Ако пусна app в main.py
Всички трейдовете които постват към панелите работят.
Иначе се дъни sqlalchemy когато трябва да прави запис от long running task към postgresql.
Postgresql бие грешка: Има активна транзакция.

Ако вдигна основния трейд (в случая app.MainLoop()) в стартиращия, scoped_session се справя със ситуацията и работи нормално.

Публикувано от: dedal 06-07-2018, 12:32
QUOTE (Gamma Goblin @ 06-07-2018, 12:19)
QUOTE
Хайде да не се съветваме на какво трябва да пиша, а да си отговаряме по темата.


Добре. В такъв случай, трябва да ти кажа, че "трейд -> trade" означава търговия.

Благодаря за урока по английски.
А нещо за програмиране можеш ли да кажеш или само на английски го докарваш?
И как е правилно да няпишеш thread на кирилица?
Мисля въпросът беше достатъчно ясен и точен!

Публикувано от: Gamma Goblin 06-07-2018, 12:34
QUOTE (dedal @ 06-07-2018, 12:32)
QUOTE (Gamma Goblin @ 06-07-2018, 12:19)
QUOTE
Хайде да не се съветваме на какво трябва да пиша, а да си отговаряме по темата.


Добре. В такъв случай, трябва да ти кажа, че "трейд -> trade" означава търговия.

Благодаря за урока по английски.
А нещо за програмиране можеш ли да кажеш или само на английски го докарваш?
И как е правилно да няпишеш thread на кирилица?
Мисля въпросът беше достатъчно ясен и точен!

"нишка" е правилно да се напише. Но Ако държиш на англицизми, може и "тред". Пусни си гугле преводач да ти го произнесе.

Публикувано от: dedal 06-07-2018, 12:48
QUOTE (Gamma Goblin @ 06-07-2018, 12:34)
QUOTE (dedal @ 06-07-2018, 12:32)
QUOTE (Gamma Goblin @ 06-07-2018, 12:19)
QUOTE
Хайде да не се съветваме на какво трябва да пиша, а да си отговаряме по темата.


Добре. В такъв случай, трябва да ти кажа, че "трейд -> trade" означава търговия.

Благодаря за урока по английски.
А нещо за програмиране можеш ли да кажеш или само на английски го докарваш?
И как е правилно да няпишеш thread на кирилица?
Мисля въпросът беше достатъчно ясен и точен!

"нишка" е правилно да се напише. Но Ако държиш на англицизми, може и "тред". Пусни си гугле преводач да ти го произнесе.

Добре поправям се нишките не работят правилно в дълго работещи задачи на графичен интерфейс който стои отворен на екрана след безкраен цикъл, до вдигане на вътрешен сигнал за затваряне на с централния кадър.
Ако кадъра стигне до бутон отварящ дълго работеща задача, която загуби връзка със устройство, таблото става бяло за 30 секунди и не отговаря кадъра. 30 секунди е времето за генериране на грешка по време на изчакване от протокол на потребителя datagram.
Ето ясно и разбираемо. А кажи как се решава?

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)