Thiết lập mối quan hệ quá trình đang chạy với tasket không thành công


9

Tôi đang cố gắng giới hạn một quá trình ở một số lõi CPU nhất định. Theo trang man tasket và tài liệu này , những điều sau đây sẽ hoạt động:

[fedora@dfarrell-opendaylight-cbench-devel ~]$ taskset -pc 0 <PID>
pid 24395's current affinity list: 0-3
pid 24395's new affinity list: 0

Nói một cách đơn giản - điều này không hiệu quả. Đặt quá trình dưới tải và xem top, nó chiếm khoảng 350% mức sử dụng CPU (giống như không có tasket). Nó sẽ tối đa ở mức 100%.

Tôi có thể thiết lập đúng mối quan hệ thông qua taskset -c 0 <cmd to start process>tại thời gian sinh sản. Sử dụng cpulimit -p <PID> -l 99cũng kinda-công trình . Trong cả hai trường hợp, việc đặt quá trình dưới cùng một kết quả tải sẽ giúp nó đạt tối đa 100% mức sử dụng CPU.

Có chuyện gì ở đây vậy?


Tôi có nên đăng cái này lên StackExchange # Unix & Linux không? Nếu vậy, ai đó có thể di chuyển nó hoặc cho tôi biết làm thế nào để di chuyển nó?
dfarrell07

Mỗi câu hỏi này , một mod cần phải di chuyển nó. Tôi sẽ đánh dấu câu hỏi cho sự chú ý của mod. Mod - vui lòng chuyển câu hỏi này đến trang web trao đổi ngăn xếp Unix và Linux. Xin lỗi vì sự nhầm lẫn!
dfarrell07

3
Như dfarrell07 đã chỉ ra, tasket không ảnh hưởng đến tất cả các luồng (LWP) của một tiến trình theo mặc định. Sử dụng tùy chọn "-a" cho tasket để ảnh hưởng đến tất cả các luồng trong tiến trình.

Tôi đã kiểm tra với một chương trình Java và có, tùy chọn -a là cần thiết (sau đó nó hoạt động đáng tin cậy). Một lưu ý khác: Không quan trọng có bao nhiêu luồng Java mới được tạo trong Java sau khi bạn chạy bộ tác vụ, giới hạn CPU vẫn được áp dụng. Rõ ràng từ "thread" có nghĩa là một cái gì đó khác hơn là một luồng Java ở đây.
Stefan Reich

Câu trả lời:


5

Tôi đã viết một tập lệnh Python chỉ đơn giản là quay vòng một số luồng và ghi các chu kỳ CPU. Ý tưởng là để kiểm tra các nhiệm vụ chống lại nó, vì nó khá đơn giản.

#!/usr/bin/env python

import threading

def cycle_burner():
    while True:
        meh = 84908230489 % 323422

for i in range(3):
    thread = threading.Thread(target=cycle_burner)
    print "Starting a thread"
    thread.start()

Chỉ cần chạy tập lệnh Python sẽ tiêu tốn khoảng 150% mức sử dụng CPU.

[~/cbench]$ ./burn_cycles.py
Starting a thread
Starting a thread
Starting a thread

Khởi chạy tập lệnh Python của tôi với tasket hoạt động như mong đợi. Xem hàng đầu cho thấy quá trình Python được chốt ở mức sử dụng 100%.

[~/cbench]$ taskset -c 0 ./burn_cycles.py
Starting a thread
Starting a thread
Starting a thread

Thật thú vị, khởi chạy tập lệnh Python và sau đó ngay lập tức sử dụng bộ tác vụ để đặt mối quan hệ của quy trình mới bắt đầu, giới hạn quy trình ở mức 100%. Lưu ý từ đầu ra rằng bộ lập lịch Linux đã hoàn thành việc thực hiện các lệnh Bash trước khi sinh ra các luồng Python. Vì vậy, quá trình Python đã được bắt đầu, sau đó nó được thiết lập để chạy trên CPU 0, sau đó nó sinh ra các luồng của nó, kế thừa mối quan hệ thích hợp.

[~/cbench]$ ./burn_cycles.py &; taskset -pc 0 `pgrep python`
[1] 8561
pid 8561's current affinity list: 0-3
pid 8561's new affinity list: 0
Starting a thread
[~/cbench]$ Starting a thread
Starting a thread

Kết quả đó tương phản với phương thức này, hoàn toàn giống nhau nhưng cho phép các luồng Python sinh ra trước khi thiết lập mối quan hệ của quy trình Python. Điều này sao chép kết quả "tasket does nothing" mà tôi đã mô tả ở trên.

[~/cbench]$ ./burn_cycles.py &
[1] 8996
[~/cbench]$ Starting a thread
Starting a thread
Starting a thread
[~/cbench]$ taskset -pc 0 `pgrep python`
pid 8996's current affinity list: 0-3
pid 8996's new affinity list: 0

Có chuyện gì ở đây vậy?

Rõ ràng các chủ đề xuất hiện trước khi mối quan hệ của quá trình cha mẹ bị thay đổi không kế thừa mối quan hệ của cha mẹ chúng. Nếu ai đó có thể chỉnh sửa trong một liên kết đến tài liệu giải thích điều này, điều đó sẽ hữu ích.


Vui lòng cập nhật câu trả lời của bạn để bao gồm tham số -anhư được đề xuất trong các nhận xét của câu hỏi. Tôi đã thử và nó làm việc cho tôi.
Nagabhushan SN

4

Tôi nghĩ rằng bạn sẽ cần phải gọi tasket một lần cho mỗi luồng, tức là sử dụng ps -eLthay vì pgrepvà chuyển nó thànhtaskset -cp 0

ps -eLo cmd,tid | grep python | perl -pe 's/.* (\d+)$/\1/' | xargs -n 1 taskset -cp 0

Lệnh gọi này được đặt cho tất cả các id luồng.


4

thay vào đó hãy thử numactl với --physcpubind(hoặc -C). Trang người đàn ông nói:

... Chính sách này được thiết lập cho mệnh lệnh và được kế thừa bởi tất cả các con của nó.

(trong các phiên bản gần đây tasksetcũng có một -atùy chọn Sets or retrieves the CPU affinity of all the tasks (threads) for a given PID.nhưng không rõ liệu nó cũng hoạt động cho các quy trình con của một tác vụ được khởi chạy hay tasksetkhông, thay vì sửa đổi quy trình đã chạy)


Trên openSUSE 42.2, -akhông hoạt động với các quy trình đã chạy.
ederag

3

Tôi sử dụng taskset's -alựa chọn thành công. Tôi có một máy chủ tên là videoconverterd tiêu thụ rất nhiều CPU; toptrình diễn

  PID USER      PR  NI    VIRT    RES    SHR S  %CPU %MEM     TIME+ COMMAND
 8991 root      20   0 1299472 346724  47380 S 385.7  4.3  42:41.37 videoconverterd

Sau khi chạy taskset -apc 0 8991, tải CPU giảm xuống

  PID USER      PR  NI    VIRT    RES    SHR S  %CPU %MEM     TIME+ COMMAND
 8991 root      20   0 1221832 293344  47380 S  99.7  3.7  49:13.28 videoconverterd

Tôi đang chạy CentOS 7 với tasksetphiên bản 2.23.2.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.