## 11.3 Working with Binary Data Record Layouts 

The struct module provides pack() and unpack() functions for working with variable length binary record formats. The following example shows how to loop through header information in a ZIP file without using the zipfile module. Pack codes$_{"H"}$ and$_{"I"}$ represent two and four byte unsigned numbers respectively. The$_{"<"}$ indicates that they are standard size and in little-endian byte order: 

import struct with open('myfile.zip','rb') as f: data =f.read() start =0 for i in range(3): # show the first 3 file headers start +=14 fields =struct.unpack( '<IIIHH ', data[start:start +16 ]) crc32, comp_size, uncomp_size, filenamesize, extra_size =fields start +=16 filename=data[start:start +filenamesize] start +=filenamesize extra =data[start:start +extra_size] print(filename, hex(crc32), comp_size, uncomp_size) start +=extra_size +comp_size # skip to the next header 

## 11.4 Multi-threading 

Threading is a technique for decoupling tasks which are not sequentially dependent. Threads can be used to improve the responsiveness of applications that accept user input while other tasks run in the background. A related use case is running I/O in parallel with computations in another thread. 

The following code shows how the high level threading module can run tasks in background while the main program continues to run: 

import threading , zipfile classAsyncZip (threading.Thread): def __init__ (self, infile, outfile): threading.Thread .__init__ (self) self.infile =infile self.outfile =outfile def run(self): f =zipfile.ZipFile(self.outfile,'w', zipfile.ZIP_DEFLATED) f.write(self.infile) f.close() print('Finished background zip of:',self.infile) background=AsyncZip('mydata.txt ','myarchive.zip') background.start() print('The main program continues to run in foreground. ') background.join() # Wait for the background task to finish print('Main program waited until background was done. ') 

The principal challenge of multi-threaded applications is coordinating threads that share data or other resources. To that end, the threading module provides a number of synchronization primitives including locks, events, condition variables, and semaphores. 

