time.sleep - นอนกระทู้หรือกระบวนการ?


คำตอบ:


353

มันบล็อกเธรด หากคุณดูใน Modules / timemodule.c ในแหล่ง Python คุณจะเห็นว่าในการเรียกไปยังfloatsleep()ส่วนสำคัญของการดำเนินการสลีปจะถูกรวมอยู่ใน Py_BEGIN_ALLOW_THREADS Py_BEGIN_ALLOW_TH และบล็อกอื่น ๆ ที่จะดำเนินการในขณะที่ปัจจุบัน หนึ่งนอน คุณสามารถทดสอบสิ่งนี้ด้วยโปรแกรมไพ ธ อนอย่างง่าย:

import time
from threading import Thread

class worker(Thread):
    def run(self):
        for x in xrange(0,11):
            print x
            time.sleep(1)

class waiter(Thread):
    def run(self):
        for x in xrange(100,103):
            print x
            time.sleep(5)

def run():
    worker().start()
    waiter().start()

สิ่งที่จะพิมพ์:

>>> thread_test.run()
0
100
>>> 1
2
3
4
5
101
6
7
8
9
10
102

3
ภาพประกอบ "ด้าย" ถูกปิดกั้นอย่างไร และทำไมไม่เพียง 5 และ 103 ไม่ได้รับการพิมพ์ในขณะที่ตัวเลขอื่น ๆ ได้รับการพิมพ์ จะเป็นประโยชน์จริง ๆ สำหรับฉันถ้ามีคนอธิบายได้
akki

@ akki: โปรดถามคำถามใหม่แทนที่จะใช้ความคิดเห็นของคำถามเก่า นอกจากนี้ 5 ยังได้รับการพิมพ์ (มันถูกต้องก่อน 101)
Nick Bastin

8
เปิดคำถามใหม่เพื่อถามความหมายของคำตอบนี้หรือไม่ มันดูค่อนข้างแปลกสำหรับฉัน และฉันหมายถึง 11 (ไม่ใช่ 5) ขออภัยไม่สามารถแก้ไขความคิดเห็นของฉันได้ในขณะนี้ ฉันต้องการความช่วยเหลือจริง ๆ แล้วเข้าใจจุดที่คำตอบนี้พยายามทำ
akki

คำตอบแรก: ฟังก์ชันช่วง xrange (k, m) ส่งกลับตัวเลข k รวมถึง m-1 รวมดังนั้นรายการนิพจน์ (xrange (100, 103)) จะส่งกลับ [100, 101, 102] ซึ่งหมายความว่าความยาว (รายการ (xrange (k, m))) == m - k
Jeff Younker

3
akki, โดยเฉพาะอย่างยิ่ง time.sleep () บล็อกเธรดที่เรียกว่า time.sleep () แต่จะเผยแพร่ Python GIL เพื่อเรียกใช้เธรดอื่น (ดังนั้นจึงไม่บล็อกกระบวนการ) ตัวอย่างของนิคไม่ได้แสดงการบล็อกของเธรดจริงๆแสดงให้เห็นว่า GIL ได้รับการปล่อยตัวมากขึ้น (ซึ่งแสดงให้เห็นว่ากระบวนการไม่ได้ถูกบล็อก) ฉันคิดว่าถ้าเขามีสิ่งอื่น ๆ เช่นคำสั่งพิมพ์หลังจาก time.sleep (5) ในบริกร () ด้ายก็จะแสดงให้เห็นว่าการพิมพ์ไม่ได้เกิดขึ้นจนกว่าหลังจาก time.sleep (5) เสร็จสิ้น (เช่นการปิดกั้น)
gunit

52

มันจะสลีปเธรดยกเว้นในกรณีที่แอปพลิเคชันของคุณมีเธรดเดียวเท่านั้นซึ่งในกรณีนั้นเธรดจะสลีปเธรดและกระบวนการได้อย่างมีประสิทธิภาพเช่นกัน

เอกสารไพ ธ อนเกี่ยวกับการนอนหลับไม่ได้ระบุสิ่งนี้อย่างไรก็ตามฉันสามารถเข้าใจความสับสนได้อย่างแน่นอน!

http://docs.python.org/2/library/time.html




13

เธรดจะบล็อก แต่กระบวนการยังมีชีวิตอยู่

ในแอปพลิเคชันเธรดเดียวหมายความว่าทุกสิ่งถูกปิดกั้นในขณะที่คุณหลับ ในแอปพลิเคชันแบบมัลติเธรดเฉพาะเธรดที่คุณ 'สลีป' อย่างชัดเจนเท่านั้นที่จะบล็อกและเธรดอื่นยังคงทำงานภายในกระบวนการ



2

กระบวนการไม่สามารถรันได้ด้วยตัวเอง ในเรื่องของการประมวลผลโพรเซสเป็นเพียงคอนเทนเนอร์สำหรับเธรด หมายความว่าคุณไม่สามารถหยุดกระบวนการได้เลย มันไม่สามารถใช้ได้กับกระบวนการ


ฮะ? สิ่งนี้อาจเป็นจริงใน Windows หรือบางสิ่ง แต่ไม่เป็นสากล ตามปกติแล้วยูนิกซ์ไม่มีเธรดเลยดังนั้นโปรแกรม Python จึงเรียกใช้โปรเซส (ด้วยเธรดเดี่ยวในบางแง่นามธรรม) ซึ่งเป็นสิ่งที่sleepคำสั่งจะหยุดชั่วคราว
tripleee

เสียใจที่ทำให้คุณผิดหวัง แต่ใน Windows และระบบ * nix ยูนิตการทำงานหลักคือ thread คุณไม่สามารถรันกระบวนการโดยไม่มีเธรด หากคุณออกจากกระทู้สุดท้ายกระบวนการจะสิ้นสุดลง
Denis The Menace

นี่ไม่ได้ตอบคำถาม โดยเฉพาะคำถามนี้เกี่ยวกับ Python Python มี Global Interpreter Lock (GIL) หากเธรดเข้าสู่โหมดสลีปในขณะที่ถือ GIL เธรดนั้นจะบล็อกเธรด Python ทั้งหมดในกระบวนการเนื่องจากพวกเขาทั้งหมดแชร์การล็อกเดียวกัน
Cort Ammon

1

มันบล็อกเธรดถ้ามันถูกดำเนินการในเธรดเดียวกันไม่ถ้ามันถูกดำเนินการจากรหัสหลัก

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.