Làm thế nào tôi có thể giết một chủ đề cụ thể của một quá trình?


21
$ ps -e -T | grep myp | grep -v grep
  797   797 ?        00:00:00 myp
  797   798 ?        00:00:00 myp
  797   799 ?        00:00:00 myp
  797   800 ?        00:00:00 myp

Điều này cho thấy quá trình mypvới PID = 797 và bốn luồng với SPID khác nhau.

Làm thế nào tôi có thể giết một luồng cụ thể của quá trình mà không giết toàn bộ quá trình. Tôi hiểu rằng có thể hoàn toàn không thể xảy ra trong một số trường hợp khi có sự phụ thuộc gây tử vong vào chủ đề cụ thể đó. Nhưng, nó có thể trong mọi trường hợp? Có, làm thế nào?

Tôi đã thử kill 799và quá trình tự nó đã chấm dứt. Bây giờ tôi không chắc chắn điều này là do có những sự phụ thuộc đã mypthất bại mà không có quá trình 800hoặc bởi vì việc giết là đơn giản không thể giết chết các quy trình riêng lẻ.

Câu trả lời:


26

Chủ đề là một phần không thể thiếu của quá trình và không thể bị giết bên ngoài nó. Có hàm pthread_kill nhưng nó chỉ áp dụng trong ngữ cảnh của chính luồng. Từ các tài liệu tại liên kết:

Lưu ý rằng pthread_kill () chỉ khiến tín hiệu được xử lý trong ngữ cảnh của luồng đã cho; hành động tín hiệu (chấm dứt hoặc dừng) ảnh hưởng đến toàn bộ quá trình.


+1. chỉ để thêm vào đây trong quá trình bạn có thể sử dụng pthread_kill () để gửi tín hiệu đến từng luồng. có thể bạn có thể thêm một số xử lý tín hiệu làm điều đó.
Hemant

@hemant: Giả sử MS Word sử dụng một chuỗi riêng biệt để kiểm tra chính tả. Giết chủ đề đó không nên làm giảm toàn bộ, trừ khi nó được thiết kế theo cách đó. Tại sao quá trình không thể tồn tại mà không có chủ đề đó trong các tình huống như thế này?
Lazer

1
Chà, tôi cho rằng bạn có thể thiết kế một mô hình luồng độc lập với quy trình cha mẹ, nhưng cho phép các quy trình bên ngoài tiêu diệt các luồng xử lý nội bộ nhưng điều đó mở ra một hộp giun liên quan đến bảo mật, quản lý quy trình và toàn vẹn hệ thống mà tôi không ' t nghĩ rằng bất kỳ nhà thiết kế hệ thống nào cũng sẵn lòng phục tùng. Threading là đủ khó mà không có những loại đau đầu. Giết một luồng từ bên trong không phải là vấn đề vì công việc được thực hiện bởi quy trình cha mẹ chịu trách nhiệm nếu có bất kỳ vấn đề nào phát sinh và có thể bị giết - tự động hoặc cách khác.
gvkv

"Trừ khi nó được thiết kế theo cách đó": Lý do chính cho việc sử dụng các luồng là chính xác để bạn có thể chia sẻ tài nguyên. Nó giống như đánh sập một nửa ngôi nhà.
pjc50

2
@Lazer, một luồng không thể kiểm tra chính tả cùng lúc với một luồng khác đang cập nhật văn bản vì bạn đang gõ. Bởi vì điều này, để có một chủ đề kiểm tra chính tả nền, nó phải làm một cái gì đó như lấy một khóa để ngăn chủ đề khác thay đổi văn bản, tạo một bản sao của một số từ, phát hành khóa, sau đó kiểm tra các từ đã sao chép trong lý lịch. Nếu bạn tình cờ giết nó trong khi nó giữ khóa, bạn sẽ treo sợi chỉ khác ngay khi bạn cố gắng gõ. Các ứng dụng đa luồng có đầy đủ các phụ thuộc nội bộ như thế này.
psusi

6

Câu trả lời chính tắc cho câu hỏi này là: Với sự hợp tác của quá trình, bằng bất kỳ cơ chế nào nó cung cấp. Nếu không có sự hợp tác của quá trình, nó là không thể. Quá trình này bao gồm các luồng là một chi tiết bên trong của quá trình, theo thiết kế có chủ ý, không được đưa ra ngoài quy trình.


Và những gì về việc gửi các tín hiệu khác từ dòng lệnh?
yucer

@yucer Tôi không chắc là tôi hiểu bạn đang hỏi gì.
David Schwartz

Tôi có nghĩa là gửi một tín hiệu khác từ danh sách được hiển thị bởi "kill -l". Tôi đang tìm cách để ra lệnh cho một luồng cụ thể để kết xuất dấu vết ngăn xếp để xem nó đang làm gì.
yucer

@yucer Đó là đặc thù của nền tảng. Một số cung cấp một cách để ra lệnh cho một luồng cụ thể để kết xuất stack. Cá nhân, tôi thấy việc sử dụng tập lệnh để đính kèm trình gỡ lỗi (thích gdb) vào quy trình sẽ dễ dàng hơn , ra lệnh cho tất cả các luồng để kết xuất ngăn xếp, sau đó tách ra.
David Schwartz

1

Trên đầu câu trả lời của @ gkv, bạn có thể xem chức năng pthread_cancel(3), một phần của <pthread.h>. Từ trang người đàn ông:

Hàm pthread_cattery () gửi yêu cầu hủy đến luồng xử lý. Việc và khi luồng đích phản ứng với yêu cầu hủy hay không phụ thuộc vào hai thuộc tính nằm dưới sự kiểm soát của luồng đó: trạng thái và loại hủy của nó.


1

Bạn có thể thấy tgkill () hữu ích. Nó là Linux cụ thể như trang người đàn ông đề cập.

tgkill () gửi tín hiệu sig đến luồng với ID luồng tid trong nhóm luồng tgid. (Ngược lại, kill (2) chỉ có thể được sử dụng để gửi tín hiệu đến toàn bộ quá trình (tức là nhóm luồng) và tín hiệu sẽ được gửi đến một luồng tùy ý trong quy trình đó.)


Điều này không giải quyết được câu hỏi về cách giết một luồng, không phải cách gửi tín hiệu đến một luồng.
David Schwartz
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.