-
Notifications
You must be signed in to change notification settings - Fork 79
Expand file tree
/
Copy pathGIL.jl
More file actions
129 lines (97 loc) · 2.83 KB
/
GIL.jl
File metadata and controls
129 lines (97 loc) · 2.83 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
"""
module PythonCall.GIL
Handling the Python Global Interpreter Lock.
See [`lock`](@ref), [`@lock`](@ref), [`unlock`](@ref) and [`@unlock`](@ref).
!!! warning
Multi-threading support is experimental and can change without notice.
"""
module GIL
using ..C: C
if Base.VERSION ≥ v"1.11"
eval(
Expr(
:public,
:lock,
Symbol("@lock"),
:unlock,
Symbol("@unlock"),
),
)
end
"""
lock(f)
Lock the GIL, compute `f()`, unlock the GIL, then return the result of `f()`.
Use this to run Python code from threads that do not currently hold the GIL, such as new
threads. Since the main Julia thread holds the GIL by default, you will need to
[`unlock`](@ref) the GIL before using this function.
See [`@lock`](@ref) for the macro form.
!!! warning
This function is experimental. Its semantics may be changed without notice.
"""
function lock(f)
state = C.PyGILState_Ensure()
try
f()
finally
C.PyGILState_Release(state)
end
end
"""
@lock expr
Lock the GIL, compute `expr`, unlock the GIL, then return the result of `expr`.
Use this to run Python code from threads that do not currently hold the GIL, such as new
threads. Since the main Julia thread holds the GIL by default, you will need to
[`@unlock`](@ref) the GIL before using this function.
The macro equivalent of [`lock`](@ref).
!!! warning
This macro is experimental. Its semantics may be changed without notice.
"""
macro lock(expr)
quote
state = C.PyGILState_Ensure()
try
$(esc(expr))
finally
C.PyGILState_Release(state)
end
end
end
"""
unlock(f)
Unlock the GIL, compute `f()`, re-lock the GIL, then return the result of `f()`.
Use this to run non-Python code with the GIL unlocked, so allowing another thread to run
Python code. That other thread can be a Julia thread, which must lock the GIL using
[`lock`](@ref).
See [`@unlock`](@ref) for the macro form.
!!! warning
This function is experimental. Its semantics may be changed without notice.
"""
function unlock(f)
state = C.PyEval_SaveThread()
try
f()
finally
C.PyEval_RestoreThread(state)
end
end
"""
@unlock expr
Unlock the GIL, compute `expr`, re-lock the GIL, then return the result of `expr`.
Use this to run non-Python code with the GIL unlocked, so allowing another thread to run
Python code. That other thread can be a Julia thread, which must lock the GIL using
[`@lock`](@ref).
The macro equivalent of [`unlock`](@ref).
!!! warning
This macro is experimental. Its semantics may be changed without notice.
"""
macro unlock(expr)
quote
state = C.PyEval_SaveThread()
try
$(esc(expr))
finally
C.PyEval_RestoreThread(state)
end
end
end
end