做多线程编程题,要根据n大小,顺序打印"010203.....0n",过程中遇到了函数引用、typing数据类型。以题目为具体代码在这里做个记录。typing的用法python文档,多线程python文档
函数引用:将函数传入线程中,如下,将 printNumber 传入三个子线程中。t_zero 绑定到 z对象的zero方法,传入参数args=(printNumber,)),其中printNumber的类型为'Callable[[int], None]',此类型表示传入参数是一个函数,该函数参数类型为int,返回值类型为None。
import threading
def printNumber(x):
print(x)
class ZeroEvenOdd:
def __init__(self, n):
pass
# printNumber(x) outputs "x", where x is an integer.
def zero(self, printNumber: 'Callable[[int], None]') -> None:
pass
def even(self, printNumber: 'Callable[[int], None]') -> None:
pass
def odd(self, printNumber: 'Callable[[int], None]') -> None:
pass
z = ZeroEvenOdd(3)
t_zero = threading.Thread(target=z.zero,args=(printNumber,))
t_odd = threading.Thread(target=z.odd,args=(printNumber,))
t_even = threading.Thread(target=z.even,args=(printNumber,))
t_zero.start()
t_odd.start()
t_even.start()
期望特定签名的回调函数的框架可以将类型标注为 Callable[[Arg1Type, Arg2Type], ReturnType]
from typing import Callable
def feeder(get_next_item: Callable[[], str]) -> None:
# Body
def async_query(on_success: Callable[[int], None],
on_error: Callable[[int, Exception], None]) -> None:
# Body
def get_next_item():
return ""
完整代码
import threading
def printNumber(x):
print(x)
class ZeroEvenOdd:
def __init__(self, n):
self.n = n
self.count = 0
self.mutex_even = threading.Lock()
self.mutex_odd = threading.Lock()
self.mutex_zero = threading.Lock()
self.mutex_even.acquire()
self.mutex_odd.acquire()
self.flag = True
# printNumber(x) outputs "x", where x is an integer.
def zero(self, printNumber: 'Callable[[int], None]') -> None:
while self.flag: ## 会导致线程无法关闭???
## while是可以用的,但是要注意每个函数的阻塞位置都在 acquire() 处。
self.mutex_zero.acquire()
if self.count < self.n:
printNumber(0)
print("---------------zero---------------")
if self.count % 2 == 0:
self.mutex_odd.release()
else:
self.mutex_even.release()
else:
self.flag = False
self.mutex_odd.release()
self.mutex_even.release()
print("----------zero done------------")
def even(self, printNumber: 'Callable[[int], None]') -> None:
while self.flag:
self.mutex_even.acquire()
if not self.flag:
return None
self.count += 1
printNumber(self.count)
print("---------------even---------------")
self.mutex_zero.release()
print("----------even done------------")
def odd(self, printNumber: 'Callable[[int], None]') -> None:
while self.flag:
self.mutex_odd.acquire()
if not self.flag:
return None
self.count += 1
printNumber(self.count)
print("---------------odd---------------")
self.mutex_zero.release()
print("----------odd done------------")
z = ZeroEvenOdd(3)
t_zero = threading.Thread(target=z.zero,args=(printNumber,))
t_odd = threading.Thread(target=z.odd,args=(printNumber,))
t_even = threading.Thread(target=z.even,args=(printNumber,))
t_zero.start()
t_odd.start()
t_even.start()
## 查询线程状态
#print(t_zero.is_alive())
#print(t_even.is_alive())
#print(t_odd.is_alive())
## 查询锁状态
# mutex.locked() ## python3.7及以上的版本支持查询锁状态