Главная / Программирование /
Язык программирования Python / Тест 11
Язык программирования Python - тест 11
Упражнение 1:
Номер 1
Как можно узнать число активных на данный момент потоков?
Ответ:
 (1) threading.enumerate()
 
 (2) threading.activeCount()
 
 (3) len(threading.enumerate())
 
 (4) threading.currentThreads()
 
Номер 2
Как можно получить список активных на данный момент потоков?
Ответ:
 (1) threading.enumerate()
 
 (2) threading.activeCount()
 
 (3) threading.active()
 
 (4) threading.currentThreads()
 
Номер 3
Предположим, что поток A
должен ждать завершения потока B
. Как этого добиться?
Ответ:
 (1) в потоке A: B.join()
 
 (2) в потоке B: A.join()
 
 (3) в потоке A: B.join(A)
 
 (4) в потоке A: A.join(B)
 
Номер 4
Z
будет использоваться в рекурсивной функции в каждом рекурсивном вызове. Какой класс выбрать для него?
Ответ:
 (1) Lock
 
 (2) RLock
 
 (3) Semaphore
 
 (4) BoundedSemaphore
 
Номер 5
Экземпляры какого класса сочетают замок и средство коммуникации между потоками?
Ответ:
 (1) Lock
 
 (2) Timer
 
 (3) Event
 
 (4) Condition
 
Упражнение 2:
Номер 1
Может ли возникнуть deadlock в следующей программе:
import threading
res_A = threading.Lock()
res_B = threading.Lock()
def proc1():
res_A.acquire()
res_B.acquire()
# ...
res_B.release()
res_A.release()
def proc2():
res_A.acquire()
res_B.acquire()
# ...
res_B.release()
res_A.release()
p1 = threading.Thread(target=proc1, name="t1")
p2 = threading.Thread(target=proc2, name="t2")
p1.start()
p2.start()
p1.join()
p2.join()
Ответ:
 (1) да, обязательно 
 (2) да, возможно 
 (3) нет, не возникнет 
Номер 2
Может ли возникнуть deadlock в следующей программе:
import threading
res_A = threading.Lock()
res_B = threading.Lock()
def proc1():
res_A.acquire()
res_B.acquire()
# ...
res_B.release()
res_A.release()
def proc2():
res_B.acquire()
res_A.acquire()
# ...
res_B.release()
res_A.release()
p1 = threading.Thread(target=proc1, name="t1")
p2 = threading.Thread(target=proc2, name="t2")
p1.start()
p2.start()
p1.join()
Ответ:
 (1) да, обязательно 
 (2) да, возможно 
 (3) нет, не возникнет 
Номер 3
Может ли возникнуть deadlock в следующей программе:
import threading
res_A = threading.Lock()
res_B = threading.Lock()
res_C = threading.Lock()
def proc1():
res_A.acquire()
res_B.acquire()
res_C.acquire()
# ...
res_C.release()
res_B.release()
res_A.release()
def proc2():
res_A.acquire()
res_B.acquire()
res_C.acquire()
# ...
res_C.release()
res_B.release()
res_A.release()
p1 = threading.Thread(target=proc1, name="t1")
p2 = threading.Thread(target=proc2, name="t2")
p1.start()
p2.start()
p1.join()
p2.join()
Ответ:
 (1) да, обязательно 
 (2) да, возможно 
 (3) нет, не возникнет 
Номер 4
Может ли возникнуть deadlock в следующей программе:
import threading
res_A = threading.Lock()
res_B = threading.Lock()
res_C = threading.Lock()
def proc1():
res_A.acquire(); res_B.acquire(); res_C.acquire()
# ...
res_B.release(); res_C.release(); res_A.release()
def proc2():
res_A.acquire(); res_B.acquire(); res_C.acquire()
# ...
res_C.release(); res_B.release(); res_A.release()
def proc3():
res_A.acquire(); res_B.acquire(); res_C.acquire()
# ...
res_A.release(); res_B.release(); res_C.release()
p1 = threading.Thread(target=proc1, name="t1")
p2 = threading.Thread(target=proc2, name="t2")
p3 = threading.Thread(target=proc3, name="t3")
p1.start(); p2.start(); p3.start()
p1.join(); p2.join(); p3.join();
Ответ:
 (1) да, обязательно 
 (2) да, возможно 
 (3) нет, не возникнет 
Номер 5
Может ли возникнуть deadlock в следующей программе:
import threading
res_A = threading.Lock()
res_B = threading.Lock()
res_C = threading.Lock()
def proc1():
res_A.acquire(); res_B.acquire(); res_C.acquire()
# ...
res_B.release(); res_C.release(); res_A.release()
def proc2():
res_B.acquire(); res_C.acquire(); res_A.acquire()
# ...
res_C.release(); res_B.release(); res_A.release()
def proc3():
res_C.acquire(); res_A.acquire(); res_B.acquire()
# ...
res_A.release(); res_B.release(); res_C.release()
p1 = threading.Thread(target=proc1, name="t1")
p2 = threading.Thread(target=proc2, name="t2")
p3 = threading.Thread(target=proc3, name="t3")
p1.start(); p2.start(); p3.start()
p1.join(); p2.join(); p3.join();
Ответ:
 (1) да, обязательно 
 (2) да, возможно 
 (3) нет, не возникнет 
Упражнение 3:
Номер 1
Что делает следующая программа?
import threading
ready = threading.Event()
def proc():
ready.wait()
# ...
print "Done!"
for i in range(5):
p = threading.Thread(target=proc)
p.start()
print "Prepare!"
ready.set()
Ответ:
 (1) программа запускает пять дополнительных потоков, печатающих "Done!"
одновременно 
 (2) программа запускает пять дополнительных потоков, печатающих "Done!"
после выполнения ready.set()
, то есть, после печати "Prepare!"
 
 (3) программа создает пять дополнительных потоков, которые запускаются после выполнения ready.set()
в главном потоке 
 (4) программа запускает пять дополнительных потоков, один из которых печатает "Done!"
после выполнения ready.set()
, а остальные ждут следующего ready.set()
 
Номер 2
Что делает следующая программа?
import threading, Queue
item = Queue.Queue()
def consumer(nm):
while True:
print item.get(), nm
def producer(nm):
while True:
item.put(nm)
for n in range(3):
threading.Thread(target=consumer, args=("c"+str(n),)).start()
threading.Thread(target=producer, args=("p"+str(n),)).start()
Ответ:
 (1) программа ничего не делает или, в некоторых случаях, успевает напечатать несколько строк вида pN cM
, после чего останавливается на попытке прочитать из пустой очереди 
 (2) программа беспрерывно печатает строки вида pN cM
, где N
— номер производителя, а M
— номер потребителя 
 (3) программа беспрерывно печатает строки вида p0 c0, p1 c1
или p2 c2
, где число после p
— номер производителя, а число после c
— номер потребителя 
 (4) программа содержит ошибку в цикле, где запускаются потоки 
Номер 3
Что делает следующая программа?
import threading
l = threading.RLock()
def proc(nm, n=0):
l.acquire()
try:
if n < 5:
print "*",
return proc(nm, n+1)
else:
return nm
finally:
l.release()
for i in range(5):
threading.Thread(target=proc, args=(str(i),)).start()
Ответ:
 (1) беспрерывно печатает звездочки 
 (2) печатает 1 звездочку и зависает 
 (3) печатает 5 звездочек 
 (4) печатает 25 звездочек 
 (5) аварийно завершается при попытке выполнить l.acquire()
во второй раз 
Номер 4
Что делает следующая программа?
import threading
l = threading.Lock()
def proc(nm, n=0):
l.acquire()
try:
if n < 5:
print "*",
return proc(nm, n+1)
else:
return nm
finally:
l.release()
for i in range(5):
threading.Thread(target=proc, args=(str(i),)).start()
Ответ:
 (1) беспрерывно печатает звездочки 
 (2) печатает 1 звездочку и зависает 
 (3) печатает 5 звездочек 
 (4) печатает 25 звездочек 
 (5) аварийно завершается при попытке выполнить l.acquire()
во второй раз 
Номер 5
Что делает следующая программа?
import threading
class PR(threading.Thread):
def __init__(self, n):
threading.Thread.__init__(self, name="t" + n)
self.n = n
def run(self):
import time
time.sleep(1)
print "*"
p1 = PR("1")
p2 = PR("2")
p1.start()
p2.start()
Ответ:
 (1) выводит две звездочки спустя секунду после запуска 
 (2) через секунду выводит звездочку, а затем через секунду — еще одну 
 (3) выводит одну звездочку и зависает 
 (4) выводит одну звездочку и завершается 
Упражнение 4:
Номер 1
В каких точках программы необходимо выполнять acquire()
и release()
замка Z
, чтобы функция f
могла правильно работать в многопоточном приложении? (Как обычно, нужно минимизировать общее время, на которое запирается замок)
def f(x, y, z):
global d1, d2
# 1
d1[(x, y)] = z
# 2
d2[z] = (x, y)
# 3
res = len(d2)
# 4
return res
Ответ:
 (1) 1: Z.acquire()
, 3: Z.release()
 
 (2) 1: Z.acquire()
, 2: Z.release()
, Z.acquire()
, 3: Z.release()
 
 (3) 1: Z.acquire()
, 4: Z.release()
 
 (4) замок не нужен 
Номер 2
В каких точках программы необходимо выполнять acquire()
и release()
замка Z
, чтобы функция f
могла правильно работать в многопоточном приложении? (Как обычно, нужно минимизировать общее время, на которое запирается замок)
def f(x, y, z):
global d
# 1
d[(x, y)] = z
# 2
res = len(d)
# 3
return res
Ответ:
 (1) 1: Z.acquire()
, 2: Z.release()
 
 (2) 1: Z.acquire()
, 2: Z.release(), Z.acquire()
, 3: Z.release()
 
 (3) 1: Z.acquire()
, 3: Z.release()
 
 (4) замок не нужен 
Номер 3
В каких точках программы необходимо выполнять acquire()
и release()
замка Z
, чтобы функция f
могла правильно работать в многопоточном приложении? (Как обычно, нужно минимизировать общее время, на которое запирается замок)
def f(x):
# 1
fc = open("file.txt", "w+")
# 2
fc.write(x)
# 3
fc.write("\n")
# 4
fc.close()
# 5
Ответ:
 (1) 1: Z.acquire()
, 5: Z.release()
 
 (2) 1: Z.acquire()
, 2: Z.release(), Z.acquire()
, 5: Z.release()
 
 (3) 2: Z.acquire()
, 4: Z.release()
 
 (4) замок не нужен 
Номер 4
Какие из фрагментов кода могут потребовать использования замков?
Ответ:
 (1) a.meth()
, где a = A()
 
 (2) a = [1, 2]
 
 (3) b = a.pop()
, где a == [1, 2]
 
 (4) a[3] = 123
, где a = B()
 
Номер 5
Какие из фрагментов кода могут потребовать использования замков?
Ответ:
 (1) a = A()
 
 (2) a = {'a':1, 'b':12}
 
 (3) a.extend([3, 4, 5])
, где a == [1, 2]
 
 (4) del a[3]
, где a = B()
 
Упражнение 5:
Номер 1
Какая ошибка допущена в следующем примере?
import threading
global to_eval
cond = threading.Condition()
def evaluate_something(x):
return 2**int(x)
def evaluator(name):
global to_eval
while True:
cond.acquire()
while not to_eval:
cond.wait()
v = to_eval.pop()
cond.release()
print name, ":", evaluate_something(v)
to_eval = []
for n in range(3):
ev = threading.Thread(target=evaluator, args=(str(n),))
ev.setDaemon(1)
ev.start()
while 1:
inp = raw_input('Вводите: ')
cond.acquire()
to_eval.append(inp)
cond.notifyAll()
cond.release()
Ответ:
 (1) cond.acquire()
должен стоять перед to_eval.pop()
 
 (2) cond.acquire()
и cond.release()
в цикле while 1
не требуется 
 (3) не обрабатываются исключения в потоках 
 (4) ошибок нет 
Номер 2
Какая ошибка допущена в следующем примере?
import threading
global to_eval
cond = threading.Condition()
def evaluate_something(x):
return 2**int(x)
def evaluator(name):
global to_eval
while True:
cond.acquire()
while not to_eval:
cond.wait()
v = to_eval.pop()
cond.release()
print name, ":", evaluate_something(v)
to_eval = []
for n in range(3):
ev = threading.Thread(target=evaluator, args=(str(n),))
ev.setDaemon(1)
ev.start()
while 1:
inp = raw_input('Вводите: ')
to_eval.append(inp)
cond.notifyAll()
Ответ:
 (1) cond.acquire()
должен стоять перед to_eval.pop()
 
 (2) в цикле while 1
требуются cond.acquire()
и cond.release()
 
 (3) не обрабатываются исключения в потоках 
 (4) ошибок нет 
Номер 3
Какая ошибка допущена в следующем примере?
def pr():
import time
time.sleep(1)
print time.time()
t = Timer(30.0, pr)
Ответ:
 (1) в потоках (кроме главного) нельзя делать time.sleep()
 
 (2) в потоках (кроме главного) нельзя делать print
 
 (3) поток с таймером не запущен 
 (4) ошибок нет 
Номер 4
В каких частях программы допущены ошибки в следующем примере?
import threading
# 1
def proc(*args):
print "Процесс в потоке пошел!"
while 1:
pass
# 2
p1 = threading.Thread(target=proc(), name="t1", args=[2])
# 3
p1.start()
Ответ:
 (1) 1 
 (2) 2 
 (3) 3 
 (4) ошибок нет 
Номер 5
Какие ошибки допущены в следующем примере?
import threading, Queue
item = Queue.Queue()
def consumer(nm):
for i in range(3):
print item.get(), nm
def producer(nm):
for i in range(4):
item.put(nm)
for n in range(4):
threading.Thread(target=consumer, args=("c"+str(n),)).start()
for n in range(3):
threading.Thread(target=producer, args=("p"+str(n),)).start()
Ответ:
 (1) потоки-потребители очереди запущены раньше потоков-производителей 
 (2) объекту, соответствующему потоку, нужно давать отдельное имя 
 (3) программа зависнет, так как производителей меньше, чем потребителей 
 (4) ошибок нет