fork
)fork
създава ново копие на програмата, която изпълнявамеimport os import time def log(msg): print "\n* %s" % msg orders = 0 while True: order = raw_input('Enter order: ') if not order: continue if order in ('q', 'x', 'quit', 'exit'): break pid = os.fork() if 0 == pid: time.sleep(3) log("Order '%s' is ready!" % order) break else: log("Roger that '%s'(%d). Please, wait in quiet desperation." % (order, orders)) orders += 1
Против:
За:
thread
— процедурен модул, стар, неудобенthreading
— ОО, нов, удобен, weapon of choicerun
start
import threading import time orders = 0 class Chef(threading.Thread): def __init__(self, order): self.order = order threading.Thread.__init__(self) def run(self): time.sleep(3) log("Order '%s' is ready!" % self.order) while True: order = raw_input('Enter order: ') if not order: continue if order in ('q', 'x', 'quit', 'exit'): break chef = Chef(order) chef.start() log("Roger that '%s'. Please, wait in quiet desperation." % order) orders += 1
import random import time import threading taken = False class Philosopher(threading.Thread): def __init__(self, name): super(Customer, self).__init__() self.name = name def log(self, msg): print "%s: %s" % (self.name, msg) def eat(self): time.sleep(random.random()) def ponder(self): time.sleep(random.random()) def refresh(self): global taken self.log("Please excuse me...") while taken: pass taken = True self.log("--> (entered the bathroom)") time.sleep(random.random()) taken = False self.log("<-- (left the bathroom)") def run(self): while True: self.eat() self.ponder() self.refresh()
threading.Lock()
ни връща Lock
обектacquire()
ни гарантира, че само ние притежаваме този Lockrelease()
освобождава Lock-а и разрешава някой друг да го заключи с acquire()
acquire()
докато Lock-а е зает — методът чака, докато не се освободиimport random import time import threading bathroom = threading.Lock() class Philosopher(threading.Thread): def __init__(self, name): super(Customer, self).__init__() self.name = name def log(self, msg): print "%s: %s" % (self.name, msg) def eat(self): time.sleep(random.random()) def ponder(self): time.sleep(random.random()) def refresh(self): self.log("Please excuse me...") bathroom.acquire() self.log("--> (entered the bathroom)") time.sleep(random.random()) bathroom.release() self.log("<-- (left the bathroom)") def run(self): while True: self.eat() self.ponder() self.refresh()
Lock
-оподбни обекти от threading
са и context manager-и with
ни се гарантира викането на acquire()
преди и на release()
след блокаwith bathroom: self.log("--> (entered the bathroom)") time.sleep(random.random()) self.log("<-- (left the bathroom)")
Или още по-добре
v
P(v)
— чакай докато v > 0
, след което v -= 1
V(v)
— v += 1
Предложени от Едсгер Дейкстра (Едсгар Дийкстра?)
threading.Semaphore(k)
ни връща семафор с интерфейс като на Lock
и стойност k
acquire()
стойността се намалява с 1release()
стойността се увеличава с 10
, acquire()
спи, докато някой не я увеличи с release()
Lock()
е еквивалентен на Semaphore(1)
import threading import random import time ovens = threading.Semaphore(5) class WaiterChef(threading.Thread): def __init__(self, name): super(WaiterChef, self).__init__() self.name = name def run(self): while True: print "...(%s) waiting for an oven" % self.name ovens.acquire() print "--> (%s) Cooking..." % self.name time.sleep(random.random() * 10) ovens.release() print "<-- (%s) Serving..." % self.name time.sleep(random.random() * 4) for _ in range(0, 10): WaiterChef(_).start()
wait()
блокира докато събитието не се случиset()
„случва“ събитиетоwait()
— чака, докато някоя баба не произведе нова баницаnotify()
— това трявба да каже една баба, която е опекла баница. Ще събуди някой от чакащите. Ако няма чакащи няма да направи нищо.notifyAll()
— ще събуди всички чакащиrelease()
и acquire()
работят върху вътрешен за Condition
Lock, който може да се подаде при конструиранеwait
и notify
работят само ако владеем вътрешния Lock
threading.local()
pickle
е модул, който може да сериализира прости Python обекти.
pickle.dump(object, file)
pickle.load(object)
from __future__ import with_statement import pickle with open('/home/bilbo/foo.txt', 'w') as file: pickle.dump("The answer", file) pickle.dump(["spam", "eggs", "ham"], file) with open('/home/bilbo/foo.txt', 'r') as file: print pickle.load(file) print pickle.load(file)
Pickle
сериализира обектите с един от три различни протокола.dumps()
и loads()
връщат сериализирана форма вместо да я записват във файл.import pickle serializedList = pickle.dumps(["spam", "eggs", "ham"]) print repr(serializedList) "(lp0\nS'spam'\np1\naS'eggs'\np2\naS'ham'\np3\na."
True
, False
и None
int
, long
, float
и complex
str
и unicode
Ако сериализирате сложна структура, в която един обект присъства два пъти (по адрес), pickle ще го сериализира еднократно.
import pickle primes = [2, 3, 5, 7, 11, 13] answer = 42 things = [primes, answer, primes] print things[0] is things[2] # True serialized = pickle.dumps(things) newThings = pickle.loads(serialized) print newThings[0] is newThings[2] # True print newThings[0] is things[0] # False
Имате достъп до същата функционалност под формата на класове:
from __future__ import with_statement import pickle with open('/home/aquarius/foo.txt', 'w') as file: pickler = pickle.Pickler(file) pickler.dump('Under the Violet Moon') pickler.dump('Soldier of Fortune') pickler.dump('Colubrid on the Tree') with open('/home/aquarius/foo.txt') as file: unpickler = pickle.Unpickler(file) print unpickler.load() print unpickler.load() print unpickler.load()
cPickle
e реализация на pickle на C, което я прави доста по-бърза.
import cPlickle as pickle ...
За сравнение:
import pickle import cPickle from timeit import Timer fancy = [[x ** 2 for x in range(0, 1000)], ["spam", "ham", "eggs"], ["-" * i for i in range(0, 1000)],] def pickleWith(pickler): serialized = pickler.dumps(fancy) restored = pickler.loads(serialized) print "pickle: ", Timer("pickleWith(pickle)", "from __main__ import *").timeit(50) print "cPickle: ", Timer("pickleWith(cPickle)", "from __main__ import *").timeit(50) # pickle: 3.28504800797 # cPickle: 0.722439050674
shelve
е сравнително прост модул, който позволява да записвате данни във файл под формата на речник.pickle
.import shelve db = shelve.open('/home/bilbo/foo.db') db['name'] = 'Mityo the Python' db['age'] = 33 db['favouriteBands'] = ["Blackmore's Night", "Deep Purple", "Rainbow"] db['favouriteSong'] = "Colubrid on the Tree" db.close() db = shelve.open('/home/bilbo/foo.db') print db.keys() print db['name'] print db['favouriteBands'] print db['favouriteSong'] db.close()