time.sleep - спить нитку чи обробляє?


Відповіді:


353

Він блокує нитку. Якщо ви подивитесь на Modules / timemodule.c у джерелі Python, ви побачите, що у виклику до floatsleep(), істотна частина операції сну загорнута у блок Py_BEGIN_ALLOW_THREADS та Py_END_ALL__READS, що дозволяє іншим потокам продовжувати виконуватись під час поточного один спить. Ви також можете перевірити це за допомогою простої програми python:

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).
Нік Бастін

8
Відкрийте нове запитання, щоб задати значення цієї відповіді? Це здається мені досить дивним. І я мав на увазі 11 (а не 5), вибачте, не можу виправити коментар зараз. Мені справді потрібна допомога, щоб зрозуміти, до чого спробувати ця відповідь.
аккі

Перша відповідь: Функція діапазону xrange (k, m) повертає числа k включно до m-1 включно, тому список виразів (xrange (100, 103)) повертається [100, 101, 102]. Це означає, що довжина (список (xrange (k, m))) == m - k.
Джефф Юнкер

3
akki, Більш конкретно, time.sleep () блокує потік, який називається time.sleep (), але він випускає Python GIL для запуску інших потоків (тому він не блокує процес). Приклад Ніка насправді не показав блокування потоку, він більше показав, що GIL звільнений (таким чином показав, що процес НЕ блокується). Я думаю, якби у нього було більше речей, як твердження про друк після time.sleep (5) у потоці офіціанта (), це показало б, що друк відбувся лише після закінчення time.sep (5) (тобто блокування)
ганіт

52

Він буде просто спати нитку, за винятком випадків, коли у вашій програмі є лише одна нитка, і в цьому випадку вона буде спати нитку і ефективно також виконувати процес.

Документація python уві сні не визначає цього, тому я, безумовно, можу зрозуміти плутанину!

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




13

Нитка блокується, але процес все ще живий.

У єдиному потоковому додатку це означає, що все заблоковано під час сну. У багатопотоковому додатку блокується лише той потік, який ви явно 'заспіваєте', а інші потоки все ще запущені в процесі.



2

Процес не піддається виконанню сам по собі. Що стосується виконання, процес є лише контейнером для ниток. Це означає, що ви взагалі не можете призупинити процес. Це просто не застосовується до процесу.


Так? Це може бути правдою для Windows або чогось іншого, але, звичайно, не повсюдно. У Unix традиційно взагалі не було потоків, і тому програма Python запускає процес (з однією ниткою, в деякому абстрактному розумінні), і саме ця sleepкоманда призупинить.
трійка

Сумно вас розчарувало, але в Windows та всіх * nix системах основний запуск - це нитка. Ви не можете запустити процес без потоків. Якщо ви виходите з останнього потоку, процес закінчується.
Денис Грозний

Це не дає відповіді на запитання. Зокрема, це питання стосується Python. У Python є глобальний замок для інтерпретаторів (GIL). Якщо нитка лягла спати, утримуючи GIL, вона б блокувала всі потоки Python у процесі, оскільки всі вони мають однаковий замок.
Корт Аммон

1

він блокує потік, якщо він виконаний у тому ж потоці, а не якщо він виконується з основного коду

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.