Bagaimana saya bisa membunuh utas proses tertentu?

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

Ini menunjukkan proses mypdengan PID = 797 dan empat utas dengan SPID yang berbeda.

Bagaimana saya bisa membunuh utas proses tertentu tanpa mematikan seluruh proses. Saya mengerti bahwa mungkin tidak mungkin sama sekali dalam beberapa kasus ketika ada ketergantungan fatal pada utas tertentu. Tetapi, apakah itu mungkin? Apakah ya, bagaimana?

Saya mencoba kill 799dan prosesnya sendiri dihentikan. Sekarang saya tidak yakin ini karena ada dependensi yang membuat mypgagal tanpa proses 800atau karena membunuh sederhana tidak dapat membunuh proses individu.

Lazer
sumber

Jawaban:

26

Thread adalah bagian integral dari proses dan tidak dapat dibunuh di luarnya. Ada fungsi pthread_kill tetapi hanya berlaku dalam konteks utas itu sendiri. Dari dokumen di tautan:

Perhatikan bahwa pthread_kill () hanya menyebabkan sinyal ditangani dalam konteks utas yang diberikan; aksi sinyal (terminasi atau penghentian) memengaruhi proses secara keseluruhan.

gvkv
sumber
+1. tambahkan saja di sini. dalam proses Anda dapat menggunakan pthread_kill () untuk mengirim sinyal ke utas individu. mungkin Anda dapat menambahkan penangan sinyal yang melakukannya.
Hemant
@ harus: Misalkan MS Word menggunakan utas terpisah untuk pemeriksaan ejaan. Membunuh utas itu seharusnya tidak menurunkan semuanya, kecuali jika dirancang seperti itu. Mengapa proses tidak dapat ada tanpa utas dalam situasi seperti ini?
Lazer
1
Yah, saya kira Anda bisa merancang model threading untuk menjadi independen dari proses induk, tetapi memungkinkan proses luar untuk membunuh thread intra-proses tetapi itu membuka kaleng cacing sehubungan dengan keamanan, manajemen proses dan integritas sistem yang saya tidak tahu. t berpikir setiap perancang sistem akan dengan sukarela menyerahkan diri. Threading cukup sulit tanpa sakit kepala semacam itu. Membunuh utas dari dalam bukanlah masalah karena pekerjaan dilakukan oleh proses induk yang bertanggung jawab jika ada masalah yang muncul dan dapat dibunuh - secara otomatis atau tidak.
gvkv
"kecuali jika dirancang seperti itu": Alasan utama untuk menggunakan utas adalah agar Anda dapat berbagi sumber daya. Ini seperti merobohkan setengah rumah.
pjc50
2
@ Lazer, satu utas tidak dapat memeriksa ejaan pada saat yang sama dengan utas lainnya memperbarui teks karena Anda mengetik. Karena itu, untuk memiliki utas pemeriksa ejaan latar belakang, ia harus melakukan sesuatu seperti ambil kunci untuk mencegah utas lainnya mengubah teks, membuat salinan beberapa kata, melepaskan kunci, lalu memeriksa kata yang disalin di Latar Belakang. Jika Anda membunuhnya saat memegang kunci, Anda akan menggantung utas lainnya segera setelah Anda mencoba mengetik. Aplikasi multithreaded penuh dengan dependensi antar seperti ini.
psusi
6

Jawaban kanonik untuk pertanyaan ini adalah: Dengan kerja sama proses, dengan mekanisme apa pun yang disediakannya. Tanpa kerja sama proses, itu tidak mungkin. Bahwa proses terdiri dari utas adalah detail internal dari proses yang, dengan desain yang disengaja, tidak diekspos di luar proses.

David Schwartz
sumber
Dan bagaimana dengan mengirim sinyal lain dari baris perintah?
Yucer
@Yucer Saya tidak yakin saya mengerti apa yang Anda minta.
David Schwartz
Maksud saya mengirim sinyal lain dari daftar yang ditunjukkan oleh "kill -l". Saya mencari cara untuk memerintahkan utas tertentu untuk membuang jejak stack untuk melihat apa yang dilakukannya.
Yucer
@Yucer Itu akan menjadi platform-spesifik. Beberapa memang menyediakan cara untuk memerintahkan utas tertentu untuk membuang tumpukan. Secara pribadi, saya merasa lebih mudah hanya menggunakan skrip untuk melampirkan debugger (seperti gdb) ke proses, memerintahkan semua utas untuk membuang tumpukan, dan kemudian lepas.
David Schwartz
1

Di atas jawaban @ gkv Anda dapat melihat fungsi pthread_cancel(3), bagian dari <pthread.h>. Dari halaman manual:

Fungsi pthread_cancel () mengirimkan permintaan pembatalan ke utas utas. Apakah dan kapan utas target bereaksi terhadap permintaan pembatalan tergantung pada dua atribut yang berada di bawah kendali utas itu: status dan jenis pembatalannya.

Ivan P
sumber
1

Anda mungkin menemukan tgkill () berguna. Ini spesifik untuk Linux seperti yang disebutkan dalam manual.

tgkill () mengirimkan sig sinyal ke utas dengan ID utas tid di grup utas tgid. (Sebaliknya, kill (2) hanya dapat digunakan untuk mengirim sinyal ke suatu proses (yaitu, grup utas) secara keseluruhan, dan sinyal akan dikirim ke utas yang sewenang-wenang dalam proses itu.)

Amit
sumber
Ini tidak menjawab pertanyaan tentang bagaimana cara membunuh utas, bukan bagaimana mengirim sinyal ke utas.
David Schwartz