ฉันจะฆ่าเธรดเฉพาะของกระบวนการได้อย่างไร


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

สิ่งนี้แสดงกระบวนการที่mypมี PID = 797 และสี่เธรดที่มี SPID ต่างกัน

ฉันจะฆ่าเธรดเฉพาะของกระบวนการโดยไม่ฆ่ากระบวนการทั้งหมดได้อย่างไร ฉันเข้าใจว่าอาจเป็นไปไม่ได้เลยในบางกรณีเมื่อมีการอ้างอิงที่ร้ายแรงในเธรดนั้น แต่มันเป็นไปได้ในกรณีใด ๆ ? ใช่แล้วเป็นอย่างไร

ฉันพยายามkill 799แล้วกระบวนการก็สิ้นสุดลง ตอนนี้ฉันไม่แน่ใจว่าเป็นเพราะมีการพึ่งพาที่ทำให้mypล้มเหลวโดยไม่มีกระบวนการ800หรือเพราะการฆ่านั้นง่ายไม่สามารถฆ่าแต่ละกระบวนการได้

คำตอบ:


26

เธรดเป็นส่วนสำคัญของกระบวนการและไม่สามารถฆ่าได้นอก มีฟังก์ชันpthread_killแต่ใช้เฉพาะในบริบทของเธรดเท่านั้น จากเอกสารที่ลิงค์:

โปรดทราบว่า pthread_kill () ทำให้สัญญาณถูกจัดการในบริบทของเธรดที่กำหนดเท่านั้น การกระทำของสัญญาณ (การยกเลิกหรือการหยุด) ส่งผลกระทบต่อกระบวนการโดยรวม


+1 เพียงเพิ่มที่นี่ ภายในกระบวนการคุณสามารถใช้ pthread_kill () เพื่อส่งสัญญาณไปยังแต่ละเธรด อาจเป็นเพราะคุณสามารถเพิ่มตัวจัดการสัญญาณซึ่งทำได้
Hemant

@hemant: สมมติว่า MS Word ใช้เธรดแยกเพื่อตรวจสอบการสะกด การฆ่าเธรดนั้นไม่ควรทำให้สิ่งทั้งหมดล้มลงเว้นแต่จะได้รับการออกแบบในลักษณะนั้น เหตุใดจึงไม่สามารถมีกระบวนการโดยไม่มีเธรดนั้นในสถานการณ์เช่นนี้
Lazer

1
ฉันคิดว่าคุณสามารถออกแบบรูปแบบการทำเกลียวให้เป็นอิสระจากกระบวนการพาเรนต์ แต่อนุญาตให้กระบวนการภายนอกฆ่าเธรดภายในกระบวนการ แต่เปิดเวิร์มของเวิร์มที่เกี่ยวกับความปลอดภัยการจัดการกระบวนการและความสมบูรณ์ของระบบที่ฉันทำ ไม่คิดว่าผู้ออกแบบระบบจะเต็มใจส่งตัวเองให้ การทำเกลียวนั้นหนักพอที่จะไม่มีอาการปวดหัวแบบนั้น การฆ่าเธรดจากด้านในนั้นไม่ใช่ปัญหาเพราะกระบวนการนี้ทำโดยผู้ปกครองซึ่งรับผิดชอบหากมีปัญหาเกิดขึ้นและสามารถถูกฆ่าได้ - โดยอัตโนมัติหรืออย่างอื่น
gvkv

"เว้นแต่จะได้รับการออกแบบในลักษณะนั้น": สาเหตุหลักของการใช้เธรดคือเพื่อให้คุณสามารถแบ่งปันทรัพยากรได้ มันค่อนข้างเหมือนกับการล้มครึ่งบ้าน
pjc50

2
@Lazer หนึ่งด้ายไม่สามารถตรวจสอบการสะกดได้ในเวลาเดียวกันเนื่องจากเธรดอื่นกำลังอัปเดตข้อความเนื่องจากคุณกำลังพิมพ์ ด้วยเหตุนี้หากต้องการให้มีการตรวจสอบการสะกดพื้นหลังของเธรดจึงต้องทำอะไรบางอย่างเช่นคว้าตัวล็อคเพื่อป้องกันไม่ให้เธรดอื่นเปลี่ยนข้อความทำสำเนาคำบางคำปลดล็อคจากนั้นตรวจสอบคำที่คัดลอกใน พื้นหลัง. หากคุณเกิดขึ้นเพื่อฆ่ามันในขณะที่มันล็อคคุณจะแขวนเธรดอื่นทันทีที่คุณพยายามพิมพ์ แอปพลิเคชันแบบมัลติเธรดเต็มไปด้วยการพึ่งพาระหว่างกันเช่นนี้
psusi

6

คำตอบที่ยอมรับได้สำหรับคำถามนี้คือ: ด้วยความร่วมมือของกระบวนการไม่ว่าจะเป็นกลไกอะไรก็ตาม หากปราศจากความร่วมมือของกระบวนการมันเป็นไปไม่ได้ การที่กระบวนการประกอบด้วยเธรดเป็นรายละเอียดภายในของกระบวนการนั่นคือโดยการออกแบบโดยเจตนาไม่เปิดเผยภายนอกกระบวนการ


แล้วการส่งสัญญาณอื่นจากบรรทัดคำสั่งล่ะ?
yucer

@yucer ฉันไม่แน่ใจว่าฉันเข้าใจสิ่งที่คุณถาม
David Schwartz

ฉันหมายถึงการส่งสัญญาณอื่นจากรายการที่แสดงโดย "kill -l" ฉันกำลังมองหาวิธีที่จะสั่งเธรดเฉพาะเพื่อดัมพ์การติดตามสแต็กเพื่อดูสิ่งที่กำลังทำอยู่
yucer

@yucer นั่นจะเป็นแพลตฟอร์มเฉพาะ บางคนมีวิธีการสั่งเธรดเฉพาะเพื่อถ่ายโอนข้อมูลกองซ้อน โดยส่วนตัวแล้วฉันพบว่าการใช้สคริปต์เพื่อแนบดีบักเกอร์ (เช่นgdb) กับกระบวนการทำได้ง่ายขึ้นสั่งการเธรดทั้งหมดเพื่อถ่ายโอนข้อมูลกองซ้อนแล้วแยกออก
David Schwartz

1

ด้านบนของคำตอบของ @ gkv คุณสามารถดูที่ฟังก์ชั่นที่เป็นส่วนหนึ่งของpthread_cancel(3) <pthread.h>จากหน้าคน:

ฟังก์ชัน pthread_cancel () ส่งคำขอยกเลิกไปยังเธรดเธรด หรือไม่และเมื่อใดที่เธรดเป้าหมายตอบสนองต่อคำร้องขอการยกเลิกขึ้นอยู่กับสองแอ็ตทริบิวต์ที่อยู่ภายใต้การควบคุมของเธรดนั้น: สถานะและประเภทการยกเลิกของมัน


1

คุณอาจพบว่าtgkill ()มีประโยชน์ มันเป็นลินุกซ์ที่เฉพาะเจาะจงเป็นหน้าคนกล่าวถึง

tgkill () ส่งสัญญาณ sig ไปยังเธรดที่มี ID เธรด tid ในกลุ่มเธรด tgid (ในทางตรงข้าม kill (2) สามารถใช้เพื่อส่งสัญญาณไปยังกระบวนการ (เช่นกลุ่มเธรด) เท่านั้นและสัญญาณจะถูกส่งไปยังเธรดที่กำหนดเองภายในกระบวนการนั้น)


สิ่งนี้ไม่ได้ตอบคำถามที่เกี่ยวกับวิธีฆ่าเธรดไม่ใช่วิธีส่งสัญญาณไปยังเธรด
David Schwartz
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.