Python 父子進程的一個示範
話說這原來是聽一個課程後的作業,需要運用父子進程的關係,來將一個檔案分解成兩個,前半部是父進程讀取寫入的,後半部是子進程讀取寫入的,寫著寫著當中添加了一些想法,後來覺得這個做出來的小程序似乎還不錯,程序中順便紀錄著其中的一些想法~ 一併跟大家分享下:
#!/usr/bin/env python3
__update__ = 'Fri 22 May, 2020 16:43'
import os
# 設定 <tab> 的功能; tab=complete 在 shell 模式下
# 可 list path
import readline, glob
def complete(text, state):
return (glob.glob(text+'*')+[None])[state]
readline.set_completer_delims('\t\n;')
readline.parse_and_bind('tab: complete')
readline.set_completer(complete)
def file_process(filename, xpid):
def rw(outfile, fseek, bs):
n = 0
try:
with open(filename, 'rb') as fr:
if fseek > 0:
fr.seek(fseek)
with open(outfile, 'wb') as fw:
print('>> 正在輸出文件名 >', outfile)
while n <= bs:
if (bs - n) < 64:
fw.write(fr.read(bs-n))
break
fw.write(fr.read(64))
n += 64
except (IOError, KeyboardInterrupt, Exception) as e:
print('[ERR#1]', e)
return False
else:
return True
if __name__ == '__main__':
ppid, pid = xpid
print('(PPID:CPID)=(%d:%d)' %(os.getpid(), os.getppid()))
fn = os.path.basename(filename)
# fpath = os.path.dirname(filename)
fsize = os.stat(filename).st_size
# 是否為父進程?
if ppid == os.getpid():
bs = (fsize // 2)
fseek = 0
outfile = 'parent_' + fn
elif pid == os.getpid():
bs = (fsize // 2)
fseek = bs
bs += (fsize % 2)
outfile = 'child_' + fn
return rw(outfile, fseek, bs)
# ===[ file_process() : End ]===
while True:
filename = input('輸入要進行讀取的文件檔案:')
if not os.path.isfile(filename):
print('> [ERR] 此文件不存在!請輸入正確路徑!')
else:
break
pid = os.fork()
if pid < 0:
print('進程創建失敗!')
elif pid == 0:
print('子進程處理中...')
print('子進程PID: %d /父進程PID: %d' %(os.getpid(), os.getppid()))
print('-'*32)
res = file_process(filename, (os.getppid(),os.getpid()) )
print('='*32)
if res:
print('子進程完成工作交付。')
else:
print('子進程工作失敗!')
os._exit(res)
else:
# pid < 0
try:
# 表 等待任意子進程的退出, 非阻塞狀態
pid, status = os.waitpid(-1, os.WNOHANG)
except ChildProcessError:
print('子進程已先退出了! 父進程準備退出...')
sleep(10) # 計畫 10 秒後退出
os._exit(2)
print('父進程處理中...')
print('父進程PID: %d /子進程PID: %d' %(os.getpid(), pid))
print('-'*32)
res = file_process(filename, (os.getpid(),pid))
print('='*32)
if res:
print('父進程完成工作交付。')
else:
print('父進程工作失敗!')
print('*** 正常退出 ***')
os._exit(res)