W3Cschool
恭喜您成為首批注冊用戶
獲得88經(jīng)驗值獎勵
You need to store state that’s specific to the currently executing thread and not visibleto other threads.
Sometimes in multithreaded programs, you need to store data that is only specific tothe currently executing thread. To do this, create a thread-local storage object usingthreading.local(). Attributes stored and read on this object are only visible to theexecuting thread and no others.As an interesting practical example of using thread-local storage, consider the LazyConnection context-manager class that was first defined in Recipe 8.3. Here is a slightlymodified version that safely works with multiple threads:
from socket import socket, AF_INET, SOCK_STREAMimport threading
class LazyConnection:def init(self, address, family=AF_INET, type=SOCK_STREAM):self.address = addressself.family = AF_INETself.type = SOCK_STREAMself.local = threading.local()def enter(self):if hasattr(self.local, ‘sock'):raise RuntimeError(‘Already connected')
self.local.sock = socket(self.family, self.type)self.local.sock.connect(self.address)return self.local.sock
def exit(self, exc_ty, exc_val, tb):self.local.sock.close()del self.local.sock
In this code, carefully observe the use of the self.local attribute. It is initialized as aninstance of threading.local(). The other methods then manipulate a socket that’sstored as self.local.sock. This is enough to make it possible to safely use an instanceof LazyConnection in multiple threads. For example:
from functools import partialdef test(conn):
with conn as s:> s.send(b'GET /index.html HTTP/1.0rn')s.send(b'Host: www.python.orgrn')
s.send(b'rn')resp = b'‘.join(iter(partial(s.recv, 8192), b'‘))
print(‘Got {} bytes'.format(len(resp)))
if name == ‘main':
conn = LazyConnection((‘www.python.org', 80))
t1 = threading.Thread(target=test, args=(conn,))t2 = threading.Thread(target=test, args=(conn,))t1.start()t2.start()t1.join()t2.join()
The reason it works is that each thread actually creates its own dedicated socket con‐nection (stored as self.local.sock). Thus, when the different threads perform socketoperations, they don’t interfere with one another as they are being performed on dif‐ferent sockets.
Creating and manipulating thread-specific state is not a problem that often arises inmost programs. However, when it does, it commonly involves situations where an objectbeing used by multiple threads needs to manipulate some kind of dedicated systemresource, such as a socket or file. You can’t just have a single socket object shared byeveryone because chaos would ensue if multiple threads ever started reading and writingon it at the same time. Thread-local storage fixes this by making such resources onlyvisible in the thread where they’re being used.In this recipe, the use of threading.local() makes the LazyConnection class supportone connection per thread, as opposed to one connection for the entire process. It’s asubtle but interesting distinction.Under the covers, an instance of threading.local() maintains a separate instancedictionary for each thread. All of the usual instance operations of getting, setting, anddeleting values just manipulate the per-thread dictionary. The fact that each thread usesa separate dictionary is what provides the isolation of data.
Copyright©2021 w3cschool編程獅|閩ICP備15016281號-3|閩公網(wǎng)安備35020302033924號
違法和不良信息舉報電話:173-0602-2364|舉報郵箱:jubao@eeedong.com
掃描二維碼
下載編程獅App
編程獅公眾號
聯(lián)系方式:
更多建議: