问题描述
目标是打印:
斐波那契编号:
斐波广场:
素数:
素数平方:
使用多线程以最多前10个子句的形式排列。
这是我的代码:
import threading
import time
def FibonacciNumbers(n):
f1 = 0
f2 = 1
if (n < 1):
return
for x in range(0,n):
print("Fibonacci No.: ")
print(f2)
time.sleep(1)
next = f1 + f2
f1 = f2
f2 = next
def FibonacciSq(n):
f1 = 0
f2 = 1
if (n < 1):
return
for x in range(0,n):
print("Square of Fibo: ")
print(f2*f2)
time.sleep(1)
next = f1 + f2
f1 = f2
f2 = next
def prime(x):
i=1
counter = 0
while True:
c=0;
for j in range (1,(i+1),1):
a = i%j
if (a==0):
c = c+1
if (c==2):
print("Prime No: ")
print (i)
time.sleep(1)
counter = counter + 1
if counter >= x:
break
i=i+1
def primeSq(x):
i=1
counter = 0
while True:
c=0;
for j in range (1,1):
a = i%j
if (a==0):
c = c+1
if (c==2):
print("Square of the Prime Number: ")
print (i*i)
time.sleep(1)
counter = counter + 1
if counter >= x:
break
i=i+1
if __name__ == "__main__":
t1 = threading.Thread(target=FibonacciNumbers,args=(10,))
t2 = threading.Thread(target=FibonacciSq,))
t3 = threading.Thread(target=prime,))
t4 = threading.Thread(target=primeSq,))
t1.start()
time.sleep(1)
# t1.join()
t2.start()
time.sleep(1)
# t2.join()
t3.start()
time.sleep(1)
# t3.join()
t4.start()
time.sleep(1)
# t4.join()
t1.join()
t2.join()
t3.join()
t4.join()
print("Done!")
我得到的结果是:
以随机方式生成输出。 我认为这是由于生成结果时发生了一些冲突。 无法弄清楚如何暂停一个线程直到下一个线程结束。 请帮助我修复输出。
Fibonacci No.:
1
Fibonacci No.:
1
Square of Fibo:
1
Fibonacci No.:
2
Square of Fibo:
1
Prime No:
2
34
Square of Fibo:
169
441
Prime No:
Square of the Prime Number:
289
Fibonacci No.:
19
55
Square of Fibo:
1156
Square of Fibo:
Square of the Prime Number:
361
3025
Prime No:
23
Square of the Prime Number:
529
Prime No:
29
Square of the Prime Number:
841
Done!
解决方法
当多个线程同时访问单个资源(在本例中为标准输出)时,您需要以某种方式同步访问(意味着:使除一个线程之外的所有线程都等到资源可以再次免费使用为止。)
根据确切的用例,有几种解决方案。最通用的解决方案是使用lock。这需要两个更改:
-
在文件的开头声明全局锁定:
lock = threading.Lock()
-
在每个函数中,将两个
print
语句包装在一个锁定的块中,例如:with lock: print("Fibonacci No.: ") print(f2)
请注意,以这种方式锁定是相当低效的操作!如果使用并发的目的是性能,那么此解决方案很可能会完全破坏目的。编写高效的多线程代码很少是琐碎的事情,而高效的同步尤其需要很多工作。 (由于最常见的Python实现使用global interpreter lock,因此增加了一些复杂性,这意味着真正基本上不会并行执行。)
在大多数情况下,最简单,实用,有效的解决方案是避免在线程之间共享资源。在您的情况下,这意味着不写任何输出(无论如何,通常都会怀疑写输出的函数):让每个函数生成结果并将其收集在列表中,或者yield
作为生成器。然后,您可以并行生成结果,并在之后顺序打印(尽管这样做需要更改,因为threading
并不容易支持返回值的函数;但是,模块{{1 }})。