1. 程式人生 > 其它 >python隨筆小題-一場針對執行緒的謀殺案

python隨筆小題-一場針對執行緒的謀殺案

話說上次大佬(@天元浪子)發新書開直播的時候前去支援了一波,在直播中有一道題目很有意思:

嘗試給一個input函式計時,如果使用者在十秒內輸入引數則顯示引數,超過十秒那就關閉輸入渠道,或者乾脆說就不讓輸了。

嗯…一看到十秒倒計時那第一反應就是time模組了(廢話)。得,先寫上唄。

import time

那接下來就是比較麻煩的一個情況,我既需要程式一邊檢測並等待使用者藉助input輸入字元,另一方面還需要程式自己給自己掐一個10秒鐘的秒錶,唉?!多程序?!
那來唄,import走起!

import multiprocessing

然後嘗試寫了兩個函式,一個是顯示input輸入:

def action
(): """使用者輸入模組""" s = input('輸入引數:') print(s)

另一個就掐時間唄:

def timeOut():
    """殺死程序模組"""
    time.sleep(10)
    """此處等待殺死上面那個函式嘿嘿嘿"""

然後就是考慮A程序啟動後得到一個程序編號(PID),然後B程序拿到這個程序編號開始計時,時間一到,按照這個編號幹它:

import multiprocessing
import
os import time def action(): """使用者輸入模組""" s = input('輸入引數:') print(s) def timeOut(): """殺死程序模組""" time.sleep(10) """此處等待殺死上面那個函式嘿嘿嘿""" os.popen('taskkill.exe /pid:' + str(os.getppid(
))) """需要說明一下,為了省事,我也不拿另一個程序的pid了,直接穩賺狠拿了父程序pid,一窩端""" if __name__ == '__main__': mp1 = multiprocessing.Process(target=action) mp1.start() mp2 = multiprocessing.Process(target=timeOut) mp2.start()

啪一下就寫完了,很快啊!執行!!!

啪嘰!!!
在這裡插入圖片描述
艹(一種植物)!!!!怎麼這麼紅?!

原來!!!
程序不支援input函式!!!
不支援input函式!!!
input函式!!!
函式!!

嗯…
嘿嘿嘿我是傻子嘿嘿嘿…

——————————————————————————————————————
吃完藥之後,我決定換個方式,程序拉倒,那就執行緒:

import threading

早知道一開始就用執行緒了,你看這個模組名字就短不少(誤)。
但是問題是,執行緒間不能通訊,那我怎麼才能讓一個執行緒到點了把另一個執行緒帶走呢???

那就是————開守護執行緒!
守護執行緒這名字聽著高大上,其實說白了,就是給某個或者某些執行緒加個daemon引數。
你比如說t1是個執行緒,那隻要在開始這個執行緒之前,這樣子:

t1.daemon = True

那這個執行緒就是守護執行緒了。
那這個執行緒開了守護能幹啥呢,你可以這麼理解:
比如一個程式由多個執行緒組成,那麼程式整體結束的標準是參照所有【非守護】執行緒是否結束。換句話說,當所有【非守護】執行緒結束的時候,程式就直接啪嘰結束了,那些還在執行的守護執行緒咋辦呢,直接強行結束。

…名字好聽,還守護執行緒,就是備胎執行緒唄。
奇怪,我怎麼突然就悟了???

——————————————————————————————————————
哭完之後,把這個程式寫出來了:

import threading
import time

def action():
    s = input('輸入引數>>> ')
    print(s)

def timeOut():
    time.sleep(10)
    print('time out!')

if __name__ == '__main__':

    t1 = threading.Thread(target=action)
    t2 = threading.Thread(target=timeOut)
    t1.daemon = True
    t1.start()
    t2.start()

本來故事到這裡就能結束了,上面這個答案也能算得上是一個標準答案。

但是

備胎這個詞不好(明明叫守護!),而且既然整個程式就倆執行緒,那麼只要在倒計時結束的時候直接強行拉閘,那什麼執行緒都要玩完,本著完(bu)美(dang)結(bei)局(tai)的想法,考慮了一下如何才能直接用python關閉當前整個程式,艾?還真可以:

import os

於是,暴力拉閘版本就整出來了:

import threading
import time
import os

def action():
    s = input('輸入引數>>> ')
    print(s)

def timeOut():
    time.sleep(10)
    print('time out!')
    os._exit(0)


if __name__ == '__main__':

    t1 = threading.Thread(target=action)
    t2 = threading.Thread(target=timeOut)
    t1.start()
    t2.start()