我最近在技术采访中得到了这个问题:
打印系列010203040506.使用多线程,第一线程将仅打印0,第二个线程仅打印均匀数字,而第3个线程仅打印奇数。
虽然我在Python上有一些经验,但我从未真正编写过任何多线程代码。因此,在阅读了一些文档后,我设法创建了可以完成工作的课程。我试图将事情放在一起,但不确定如何解决。有人可以帮助我提供基于锁或信号的解决方案吗?
import threading
class PrintSeries(threading.Thread):
def __init__(self, start, stop, step, string):
threading.Thread.__init__(self)
self.string = string
self.start = start
self.stop = stop
self.step = step
def run(self):
if self.start < self.stop:
self.start += self.step
self.string += str(self.start)
s = ''
t1 = PrintSeries(0, 0, 0, s)
t2 = PrintSeries(1, 2, 5, s)
t3 = PrintSeries(2, 2, 6, s)
t1.start()
t2.start()
t3.start()
t1.join()
t2.join()
t3.join()
print(s)
无论如何,即使这也陷入以下错误,
t1.start()
TypeError: 'int' object is not callable
这是一种使用条件对象的解决方案
使用条件变量的典型编程样式使用锁 同步对某些共享状态的访问;线程 对反复的州呼叫wait((的特定更改感兴趣 直到他们看到所需的状态,而在修改状态的线程 当他们以这种方式更改状态时呼叫notify((或notifyall(( 对于一个服务员之一来说,这可能是理想的状态
预期的执行序列为(T1,T3,T1,T2,T1,T3,...(,因此我们只创建一个持有当前状态的状态变量,并且每个线程只有在满足预期条件时才有效。之后,它将更新状态并唤醒其他线程
from threading import Thread, Lock, Condition
def zero_printer(max_iters):
global state
for _ in range(max_iters):
with cv:
while state not in (0, 2):
cv.wait()
state += 1
print('0')
cv.notify_all()
def even_printer(max_iters):
global state
c = 2
for _ in range(max_iters):
with cv:
while state != 3:
cv.wait()
print(c)
state = 0
cv.notify_all()
c += 2
def odd_printer(max_iters):
global state
c = 1
for _ in range(max_iters):
with cv:
while state != 1:
cv.wait()
print(c)
state = 2
cv.notify_all()
c += 2
iters = 3
state = 0
cv = Condition(Lock())
t1 = Thread(target=zero_printer, args=(iters * 2,))
t2 = Thread(target=even_printer, args=(iters,))
t3 = Thread(target=odd_printer, args=(iters,))
t1.start()
t2.start()
t3.start()
t1.join()
t2.join()
t3.join()
结果:
0
1
0
2
0
3
0
4
0
5
0
6
我不必费心将其组合到一行中。
代码中的错误是,您正在滥用threading.Thread
构造函数,即作为Expectet target 参数传递整数值,因此它试图执行您的 int> int value和产生了相应的错误消息