Python 将 class 限制为单个实例?
Python limit class to single instance?
我有一个 cherryPy 服务器,除其他外,访问需要访问一个 "single instance resource"。
单实例资源是与另一个设备的串行通信,需要执行一整套操作才能释放以供再次访问。
cherryPy 的定义是多线程的,我想保持这种状态。
如何通过管道访问这一单一资源?
我能想到的最好办法是添加一个 class 属性 "busy" 并在执行对单个资源的访问之前检查其状态。
让我感到困惑的是 commClass.init print 只打印一次。
# ========= IMPORTS =============
import cherrypy
import simplejson
import os
import time
import random
class commClass:
busy = False
instance = 0
def __init__(self, uid):
self.uid = uid
commClass.instance += 1
print("INIT:", self.uid, "INST:", commClass.instance)
def singleResource(self, periods):
for i in range (0, periods):
print("ID:", self.uid, " WASTE TIME:", i)
time.sleep(1)
PATH = os.path.abspath(os.path.dirname(__file__))
comm = commClass(random.randrange(0, 1000))
def wasteTime():
global comm
while comm.busy:
print("busy...")
time.sleep(0.5)
comm.busy = True
comm.singleResource(5)
comm.busy = False
# ============== Main Server Object ======
class threadTest(object):
def __init__(self):
pass
@cherrypy.expose
@cherrypy.tools.json_out()
def wasteTime(self):
wasteTime()
servResponse = dict()
return simplejson.dumps(dict(servResponse))
conf = {'/':
{
'tools.staticdir.on': True,
'tools.staticdir.dir': PATH,
'tools.staticdir.index': 'cherryPyThreadTest.html',
}
}
if __name__=='__main__':
print("Server _ON_")
#print(Labyrinth.ip)
cherrypy.server.socket_host = '0.0.0.0'
cherrypy.server.thread_pool = 30
cherrypy.server.socket_port = 80
cherrypy.quickstart(threadTest(), '/', conf)
输出符合预期:
INIT: 643 INST: 1
Server _ON_
ID: 643 WASTE TIME: 0
busy...
busy...
ID: 643 WASTE TIME: 1
busy...
busy...
ID: 643 WASTE TIME: 2
busy...
busy...
ID: 643 WASTE TIME: 3
busy...
busy...
ID: 643 WASTE TIME: 4
busy...
busy...
192.168.252.142 - - [18/Dec/2018:11:22:24] "POST /wasteTime HTTP/1.1" 200 4 "http://xxx.xxx.xxx.xxx/" "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36"
ID: 643 WASTE TIME: 0
ID: 643 WASTE TIME: 1
ID: 643 WASTE TIME: 2
ID: 643 WASTE TIME: 3
ID: 643 WASTE TIME: 4
您想要的是一种锁,可以防止多个线程同时 运行 执行该功能。
import threading
class Comm(object):
def __init__(self, uid):
self.lock = threading.Lock()
self.uid = uid
def singleResource(self, periods):
with self.lock:
for i in range (0, periods):
print("ID:", self.uid, " WASTE TIME:", i)
time.sleep(1)
comm = Comm(0)
def wasteTime():
comm.singleResource(5)
我有一个 cherryPy 服务器,除其他外,访问需要访问一个 "single instance resource"。 单实例资源是与另一个设备的串行通信,需要执行一整套操作才能释放以供再次访问。
cherryPy 的定义是多线程的,我想保持这种状态。 如何通过管道访问这一单一资源? 我能想到的最好办法是添加一个 class 属性 "busy" 并在执行对单个资源的访问之前检查其状态。
让我感到困惑的是 commClass.init print 只打印一次。
# ========= IMPORTS =============
import cherrypy
import simplejson
import os
import time
import random
class commClass:
busy = False
instance = 0
def __init__(self, uid):
self.uid = uid
commClass.instance += 1
print("INIT:", self.uid, "INST:", commClass.instance)
def singleResource(self, periods):
for i in range (0, periods):
print("ID:", self.uid, " WASTE TIME:", i)
time.sleep(1)
PATH = os.path.abspath(os.path.dirname(__file__))
comm = commClass(random.randrange(0, 1000))
def wasteTime():
global comm
while comm.busy:
print("busy...")
time.sleep(0.5)
comm.busy = True
comm.singleResource(5)
comm.busy = False
# ============== Main Server Object ======
class threadTest(object):
def __init__(self):
pass
@cherrypy.expose
@cherrypy.tools.json_out()
def wasteTime(self):
wasteTime()
servResponse = dict()
return simplejson.dumps(dict(servResponse))
conf = {'/':
{
'tools.staticdir.on': True,
'tools.staticdir.dir': PATH,
'tools.staticdir.index': 'cherryPyThreadTest.html',
}
}
if __name__=='__main__':
print("Server _ON_")
#print(Labyrinth.ip)
cherrypy.server.socket_host = '0.0.0.0'
cherrypy.server.thread_pool = 30
cherrypy.server.socket_port = 80
cherrypy.quickstart(threadTest(), '/', conf)
输出符合预期:
INIT: 643 INST: 1
Server _ON_
ID: 643 WASTE TIME: 0
busy...
busy...
ID: 643 WASTE TIME: 1
busy...
busy...
ID: 643 WASTE TIME: 2
busy...
busy...
ID: 643 WASTE TIME: 3
busy...
busy...
ID: 643 WASTE TIME: 4
busy...
busy...
192.168.252.142 - - [18/Dec/2018:11:22:24] "POST /wasteTime HTTP/1.1" 200 4 "http://xxx.xxx.xxx.xxx/" "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36"
ID: 643 WASTE TIME: 0
ID: 643 WASTE TIME: 1
ID: 643 WASTE TIME: 2
ID: 643 WASTE TIME: 3
ID: 643 WASTE TIME: 4
您想要的是一种锁,可以防止多个线程同时 运行 执行该功能。
import threading
class Comm(object):
def __init__(self, uid):
self.lock = threading.Lock()
self.uid = uid
def singleResource(self, periods):
with self.lock:
for i in range (0, periods):
print("ID:", self.uid, " WASTE TIME:", i)
time.sleep(1)
comm = Comm(0)
def wasteTime():
comm.singleResource(5)