Use cythonize --build cysleep.pyx
After building, run python main.py
# cython: language_level=3 | |
cdef extern from 'time.h': | |
ctypedef long time_t | |
cdef struct timespec: | |
time_t tv_sec | |
long tv_nsec | |
void nanosleep(const timespec*, timespec*) nogil | |
def sleep_gil(time: float): | |
cdef time_t seconds = round(time) | |
cdef timespec sleep_time = timespec(seconds, int((time - seconds) * 10**9)) | |
nanosleep(&sleep_time, NULL) | |
def sleep_nogil(time: float): | |
cdef time_t seconds = round(time) | |
cdef timespec sleep_time = timespec(seconds, int((time - seconds) * 10**9)) | |
with nogil: | |
nanosleep(&sleep_time, NULL) |
import threading | |
from kivy.app import App | |
from kivy.clock import Clock | |
from kivy.lang import Builder | |
from kivy.properties import BooleanProperty, NumericProperty | |
from cysleep import sleep_gil, sleep_nogil | |
KV = ''' | |
BoxLayout: | |
orientation: 'vertical' | |
ToggleButton: | |
text: 'Use nogil' | |
on_state: app.use_nogil = self.state == 'down' | |
Button: | |
text: 'Sleep now' | |
on_press: app.sleep() | |
canvas: | |
Color: | |
Ellipse: | |
pos: | |
( | |
self.center_x - self.texture_size[0] / 2 - 90, | |
self.center_y - 30 | |
) | |
size: 60, 60 | |
angle_end: app.time * 360 % 360 | |
''' | |
class SleepTest(App): | |
use_nogil = BooleanProperty(False) | |
time = NumericProperty() | |
def build(self): | |
def update_time(dt): | |
self.time += dt | |
Clock.schedule_interval(update_time, 0) | |
return Builder.load_string(KV) | |
def sleep(self): | |
if self.use_nogil: | |
target = sleep_nogil | |
else: | |
target = sleep_gil | |
threading.Thread(target=target, args=(1,)).start() | |
SleepTest().run() |