Câu hỏi: Vì việc sử dụng "Gil" của Python có khả năng chạy các luồng riêng biệt của nó không?
Info:
Sau khi đọc điều này, tôi đã ra đi khá không chắc chắn về việc Python có khả năng tận dụng bộ xử lý đa lõi hay không. Cũng được thực hiện như Python, nó cảm thấy thực sự kỳ lạ khi nghĩ rằng nó sẽ thiếu một khả năng mạnh mẽ như vậy. Vì vậy, cảm thấy không chắc chắn, tôi quyết định hỏi ở đây. Nếu tôi viết một chương trình đa luồng, nó sẽ có khả năng thực hiện đồng thời trên nhiều lõi?
Hỏi ngày 25 tháng 9 năm 2011 lúc 1:00Sep 25, 2011 at 1:00
NarcolapsercolapserNarcolapser
5.58714 Huy hiệu vàng45 Huy hiệu bạc55 Huy hiệu Đồng14 gold badges45 silver badges55 bronze badges
2
Câu trả lời là "Có, nhưng ..."
Nhưng Cpython không thể khi bạn đang sử dụng các luồng thông thường cho đồng thời.
Bạn có thể sử dụng một cái gì đó như multiprocessing
, celery
hoặc mpi4py
để chia công việc song song thành một quy trình khác;
Hoặc bạn có thể sử dụng một cái gì đó như Jython hoặc Ironpython để sử dụng một trình thông dịch thay thế không có Gil.
Một giải pháp nhẹ nhàng hơn là sử dụng các thư viện không chạy Afoul của GIL cho các nhiệm vụ CPU nặng, ví dụ numpy
có thể thực hiện việc nâng vật nặng trong khi không giữ lại GIL, vì vậy các chủ đề Python khác có thể tiến hành. Bạn cũng có thể sử dụng thư viện ctypes
theo cách này.
Nếu bạn không thực hiện công việc ràng buộc CPU, bạn có thể bỏ qua vấn đề GIL hoàn toàn [loại] vì Python sẽ không có được GIL trong khi đang chờ IO.
Andrei
10,4K10 Huy hiệu vàng76 Huy hiệu bạc 108 Huy hiệu đồng10 gold badges76 silver badges108 bronze badges
Đã trả lời ngày 25 tháng 9 năm 2011 lúc 1:06Sep 25, 2011 at 1:06
5
Chủ đề Python không thể tận dụng nhiều lõi. Điều này là do một chi tiết triển khai nội bộ được gọi là GIL [Khóa thông dịch toàn cầu] trong việc triển khai C của Python [CPython], gần như chắc chắn là những gì bạn sử dụng.threads cannot take advantage of many cores. This is due to an internal implementation detail called the GIL [global interpreter lock] in the C implementation of python [cPython] which is almost certainly what you use.
Giải pháp thay thế là mô-đun multiprocessing
//www.python.org/dev/peps/pep-0371/ được phát triển cho mục đích này.multiprocessing
module
//www.python.org/dev/peps/pep-0371/ which was developed for this purpose.
Tài liệu: //docs.python.org/l Library/multiprocessing.html
[Hoặc sử dụng ngôn ngữ song song.]
Đã trả lời ngày 25 tháng 9 năm 2011 lúc 1:06Sep 25, 2011 at 1:06
Chủ đề Python không thể tận dụng nhiều lõi. Điều này là do một chi tiết triển khai nội bộ được gọi là GIL [Khóa thông dịch toàn cầu] trong việc triển khai C của Python [CPython], gần như chắc chắn là những gì bạn sử dụng.ninjagecko
Giải pháp thay thế là mô-đun multiprocessing
//www.python.org/dev/peps/pep-0371/ được phát triển cho mục đích này.24 gold badges134 silver badges143 bronze badges
2
Tài liệu: //docs.python.org/l Library/multiprocessing.html
[Hoặc sử dụng ngôn ngữ song song.]
Ninjageckoninjagecko
85,9K24 Huy hiệu vàng134 Huy hiệu bạc143 Huy hiệu đồngSep 25, 2011 at 1:04
CPYThon [triển khai Python cổ điển và phổ biến của Python] không thể có nhiều hơn một luồng thực thi mã byte Python cùng một lúc. Điều này có nghĩa là các chương trình giới hạn tính toán sẽ chỉ sử dụng một lõi. Các hoạt động I/O và tính toán xảy ra bên trong các phần mở rộng C [như Numpy] có thể hoạt động đồng thời.Ned Batchelder
Việc thực hiện Python khác [như Jython hoặc Pypy] có thể hoạt động khác nhau, tôi không rõ ràng về chi tiết của họ.71 gold badges554 silver badges650 bronze badges
1
Khuyến nghị thông thường là sử dụng nhiều quy trình thay vì nhiều chủ đề.
but also to the answer to "threaded or multi-processing?":
Đã trả lời ngày 25 tháng 9 năm 2011 lúc 1:04
--[ With other processes running including htop ]
- Ned Batchelderned Batchelder
but multi-processing was more efficient than threading for cpu-bound.
354K71 Huy hiệu vàng554 Huy hiệu bạc650 Huy hiệu Đồng
Như đã nêu trong các câu trả lời trước - nó phụ thuộc vào câu trả lời cho "CPU hoặc I/O bị ràng buộc?", Nhưng cũng là câu trả lời cho "Chủ đề hoặc đa xử lý?":
. Starting 4000 cycles of io-bound threading
. Sequential run time: 39.15 seconds
. 4 threads Parallel run time: 18.19 seconds
. 2 threads Parallel - twice run time: 20.61 seconds
Các ví dụ chạy trên Raspberry PI 3B 1.2GHz 4-core với Python3.7.3-[với các quy trình khác đang chạy bao gồm HTOP]
. Starting 1000000 cycles of cpu-only threading
. Sequential run time: 9.39
seconds
. 4 threads Parallel run time: 10.19 seconds
. 2 threads Parallel twice - run time: 9.58 seconds
Đối với thử nghiệm này-đa xử lý và phân luồng có kết quả tương tự đối với I/O bị ràng buộc, nhưng đa xử lý có hiệu quả hơn so với việc xâu chuỗi đối với liên kết CPU.
Sử dụng các chủ đề:
. Starting 4000 cycles of io-bound processing
. Sequential - run time: 39.74 seconds
. 4 procs Parallel - run time: 17.68 seconds
. 2 procs Parallel twice - run time: 20.68 seconds
Kết quả điển hình:. Bắt đầu 4000 chu kỳ của chuỗi IO. Thời gian chạy tuần tự: 39,15 giây. 4 Chủ đề Thời gian chạy song song: 18,19 giây. 2 Chủ đề song song - Thời gian chạy hai lần: 20,61 giây
. Starting 1000000 cycles of cpu-only processing
. Sequential run time: 9.24 seconds
. 4 procs Parallel
- run time: 2.59 seconds
. 2 procs Parallel twice - run time: 4.76 seconds
compare_io_multiproc.py:
#!/usr/bin/env python3
# Compare single proc vs multiple procs execution for io bound operation
"""
Typical Result:
Starting 4000 cycles of io-bound processing
Sequential - run time: 39.74 seconds
4 procs Parallel - run time: 17.68 seconds
2 procs Parallel twice - run time: 20.68 seconds
"""
import time
import multiprocessing as mp
# one thousand
cycles = 1 * 1000
def t[]:
with open['/dev/urandom', 'rb'] as f:
for x in range[cycles]:
f.read[4 * 65535]
if __name__ == '__main__':
print[" Starting {} cycles of io-bound processing".format[cycles*4]]
start_time = time.time[]
t[]
t[]
t[]
t[]
print[" Sequential - run time: %.2f seconds" % [time.time[] - start_time]]
# four procs
start_time = time.time[]
p1 = mp.Process[target=t]
p2 = mp.Process[target=t]
p3 = mp.Process[target=t]
p4 = mp.Process[target=t]
p1.start[]
p2.start[]
p3.start[]
p4.start[]
p1.join[]
p2.join[]
p3.join[]
p4.join[]
print[" 4 procs Parallel - run time: %.2f seconds" % [time.time[] - start_time]]
# two procs
start_time = time.time[]
p1 = mp.Process[target=t]
p2 = mp.Process[target=t]
p1.start[]
p2.start[]
p1.join[]
p2.join[]
p3 = mp.Process[target=t]
p4 = mp.Process[target=t]
p3.start[]
p4.start[]
p3.join[]
p4.join[]
print[" 2 procs Parallel twice - run time: %.2f seconds" % [time.time[] - start_time]]
compare_cpu_multiproc.py
#!/usr/bin/env python3
# Compare single proc vs multiple procs execution for cpu bound operation
"""
Typical Result:
Starting 1000000 cycles of cpu-only processing
Sequential run time: 9.24 seconds
4 procs Parallel - run time: 2.59 seconds
2 procs Parallel twice - run time: 4.76 seconds
"""
import time
import multiprocessing as mp
# one million
cycles = 1000 * 1000
def t[]:
for x in range[cycles]:
fdivision = cycles / 2.0
fcomparison = [x > fdivision]
faddition = fdivision + 1.0
fsubtract = fdivision - 2.0
fmultiply = fdivision * 2.0
if __name__ == '__main__':
print[" Starting {} cycles of cpu-only processing".format[cycles]]
start_time = time.time[]
t[]
t[]
t[]
t[]
print[" Sequential run time: %.2f seconds" % [time.time[] - start_time]]
# four procs
start_time = time.time[]
p1 = mp.Process[target=t]
p2 = mp.Process[target=t]
p3 = mp.Process[target=t]
p4 = mp.Process[target=t]
p1.start[]
p2.start[]
p3.start[]
p4.start[]
p1.join[]
p2.join[]
p3.join[]
p4.join[]
print[" 4 procs Parallel - run time: %.2f seconds" % [time.time[] - start_time]]
# two procs
start_time = time.time[]
p1 = mp.Process[target=t]
p2 = mp.Process[target=t]
p1.start[]
p2.start[]
p1.join[]
p2.join[]
p3 = mp.Process[target=t]
p4 = mp.Process[target=t]
p3.start[]
p4.start[]
p3.join[]
p4.join[]
print[" 2 procs Parallel twice - run time: %.2f seconds" % [time.time[] - start_time]]
Kết quả điển hình:. Bắt đầu 1000000 chu kỳ của chuỗi chỉ CPU. Thời gian chạy tuần tự: 9,39 giây. 4 Chủ đề Thời gian chạy song song: 10,19 giây. 2 Chủ đề song song hai lần - Thời gian chạy: 9,58 giâyJan 24, 2021 at 15:07
Sử dụng đa xử lý:
import time
import threading
def t[]:
with open['/dev/urandom'] as f:
for x in xrange[100]:
f.read[4 * 65535]
if __name__ == '__main__':
start_time = time.time[]
t[]
t[]
t[]
t[]
print "Sequential run time: %.2f seconds" % [time.time[] - start_time]
start_time = time.time[]
t1 = threading.Thread[target=t]
t2 = threading.Thread[target=t]
t3 = threading.Thread[target=t]
t4 = threading.Thread[target=t]
t1.start[]
t2.start[]
t3.start[]
t4.start[]
t1.join[]
t2.join[]
t3.join[]
t4.join[]
print "Parallel run time: %.2f seconds" % [time.time[] - start_time]
result:
$ python 1.py
Sequential run time: 3.69 seconds
Parallel run time: 4.82 seconds
Kết quả điển hình:. Bắt đầu 4000 chu kỳ xử lý IO. Tuần tự - Thời gian chạy: 39,74 giây. 4 Procs song song - Thời gian chạy: 17,68 giây. 2 Procs song song hai lần - Thời gian chạy: 20,68 giâyMar 16, 2016 at 4:50
Kết quả điển hình:. Bắt đầu 1000000 chu kỳ xử lý chỉ CPU. Thời gian chạy tuần tự: 9,24 giây. 4 Procs song song - Thời gian chạy: 2,59 giây. 2 Procs song song hai lần - Thời gian chạy: 4,76 giâyest
Đã trả lời ngày 24 tháng 1 năm 2021 lúc 15:0713 gold badges67 silver badges117 bronze badges
4
Mã ví dụ lấy tất cả 4 lõi trên Ubuntu 14.04 của tôi, Python 2.7 64 bit.
import time
import threading
def t[]:
with open['/dev/urandom', 'rb'] as f:
for x in range[100]:
f.read[4 * 65535]
if __name__ == '__main__':
start_time = time.time[]
t[]
t[]
t[]
t[]
print["Sequential run time: %.2f seconds" % [time.time[] - start_time]]
start_time = time.time[]
t1 = threading.Thread[target=t]
t2 = threading.Thread[target=t]
t3 = threading.Thread[target=t]
t4 = threading.Thread[target=t]
t1.start[]
t2.start[]
t3.start[]
t4.start[]
t1.join[]
t2.join[]
t3.join[]
t4.join[]
print["Parallel run time: %.2f seconds" % [time.time[] - start_time]]
Đã trả lời ngày 16 tháng 3 năm 2016 lúc 4:50
Estest11.1K13 Huy hiệu vàng67 Huy hiệu bạc117 Huy hiệu đồng
Tôi đã chuyển đổi tập lệnh thành Python3 và chạy nó trên Raspberry Pi 3B+:Apr 14, 2018 at 1:06
1
Python3 T.Py
85,9K24 Huy hiệu vàng134 Huy hiệu bạc143 Huy hiệu đồngSep 25, 2011 at 1:04
CPYThon [triển khai Python cổ điển và phổ biến của Python] không thể có nhiều hơn một luồng thực thi mã byte Python cùng một lúc. Điều này có nghĩa là các chương trình giới hạn tính toán sẽ chỉ sử dụng một lõi. Các hoạt động I/O và tính toán xảy ra bên trong các phần mở rộng C [như Numpy] có thể hoạt động đồng thời.Profane
Việc thực hiện Python khác [như Jython hoặc Pypy] có thể hoạt động khác nhau, tôi không rõ ràng về chi tiết của họ.8 silver badges13 bronze badges