bagaimana cara mendapatkan id utas dari pthread di program linux c?

94

Dalam program linux c, bagaimana cara mencetak id thread dari sebuah thread yang dibuat oleh pthread library?
sebagai contoh: kita bisa mendapatkan pid dari sebuah proses dengangetpid()

Ravi Chandra
sumber

Jawaban:

81

pthread_self() fungsi akan memberikan id utas utas saat ini.

The pthread_self()mengembalikan fungsi pthread pegangan thread menelepon. Fungsi pthread_self () TIDAK mengembalikan utas integral utas pemanggil. Anda harus menggunakan pthread_getthreadid_np()untuk mengembalikan pengenal integral untuk utas.

CATATAN:

jauh lebih cepat daripada panggilan ini, tetapi memberikan perilaku yang sama.

Abhitesh khatri
sumber
38
Pertanyaan aslinya adalah tentang Linux. Linux tidak menyertakan fungsi _np. (Tidak termasuk halaman manual mereka, saya tidak memeriksa lebih jauh dari itu.)
Trade-Ideas Philip
pthread_threadid_np tersedia di OS X> = 10.6 dan iOS> = 3.2.
Bleater
@Bleater Bisakah Anda memberikan dokumentasi resmi untuk pthread_threadid_np. Saya perlu menggunakan untuk sebuah proyek, jadi perlu memeriksa keandalan API itu di platform iOS dan OSX. Merujuk tautan di opensource.apple.com/source/Libc/Libc-583/pthreads/pthread.h tetapi tidak yakin apakah itu yang benar.
Vivek Maran
@Vivek Saya tidak memiliki tautan apa pun ke dokumen resmi, hanya tajuk yang Anda tautkan dan sumbernya di opensource.apple.com/source/Libc/Libc-583/pthreads/pthread.c
bleater
10
@ Trade-IdeasPhilip - Untuk memperjelas, _npberarti non-portabel. Linux memiliki _npbarang - barangnya sendiri , tetapi tidak termasuk milik Apple pthread_getthreadid_np.
Josh Kelley
85

Apa? Orang tersebut meminta untuk spesifik Linux, dan yang setara dengan getpid (). Bukan BSD atau Apple. Jawabannya adalah gettid () dan mengembalikan tipe integral. Anda harus memanggilnya menggunakan syscall (), seperti ini:

Meskipun ini mungkin tidak portabel untuk sistem non-linux, threadid ini secara langsung dapat dibandingkan dan sangat cepat untuk diperoleh. Dapat dicetak (seperti untuk LOG) seperti bilangan bulat biasa.

Evan Langlois
sumber
11
Ini seharusnya jawaban yang benar
Matthew S
Orang tersebut bertanya tentang sesuatu yang bekerja di Linux. Melakukannya dengan cara portabel menurut saya seperti cara yang lebih disukai untuk melakukannya. Jika portabilitas tidak dihitung untuk apa pun maka saya kira Linux benar-benar menjadi Windows baru ...
Jasper Siepkes
3
@Jas Sikes Anda melewatkan intinya. Dia meminta panggilan LINUX yang setara dengan getpid () untuk utas. Itu adalah gettid (). Pertanyaannya tidak menanyakan tentang portabilitas atau POSIX. Terlalu banyak orang ingin pamer dan mencoba dan mengajar daripada mengajukan pertanyaan seperti yang ditanyakan. pthread_self () tidak mengembalikan id utas kernel dan tidak dapat dimanipulasi dengan cara yang memudahkan pencetakan. Selain itu, pthread_self kemungkinan besar adalah pointer dan tidak boleh dimanipulasi, hanya dibandingkan dengan pthread_equal (). Pertanyaan menanyakan ID yang dapat Anda cetak, dan itu gettid ().
Evan Langlois
3
@EvanLanglois Dia bekerja dengan pustaka pthread, secara harfiah pustaka utas POSIX. Membuat jawaban yang kompatibel dengan POSIX tidaklah aneh. "Dia meminta panggilan LINUX yang setara dengan getpid () untuk utas." Tidak, getpid()diberikan sebagai contoh. Itu tidak mengatakan bahwa semantik adalah spesifikasi yang sulit. Membuat orang sadar melakukan sesuatu dengan cara yang kompatibel dengan POSIX sehingga komunitas lain selain Linux (seperti FreeBSD, Illumos, OS X, dll.) Dapat mengambil keuntungan darinya bukanlah "pamer". Seperti yang saya katakan, saya kira Linux benar-benar telah menjadi Windows berikutnya.
Jasper Siepkes
14

Seperti dicatat dalam jawaban lain, pthreads tidak menentukan cara yang tidak bergantung platform untuk mengambil ID utas integral.

Pada sistem Linux, Anda bisa mendapatkan ID utas sebagai berikut:

Pada banyak platform berbasis BSD, jawaban https://stackoverflow.com/a/21206357/316487 ini memberikan cara non-portabel.

Namun, jika alasan Anda merasa memerlukan ID utas adalah untuk mengetahui apakah Anda menjalankan utas yang sama atau berbeda ke utas lain yang Anda kontrol, Anda mungkin menemukan beberapa utilitas dalam pendekatan ini.

Jika Anda hanya perlu tahu apakah Anda berada di utas utama, ada cara tambahan, yang didokumentasikan dalam jawaban atas pertanyaan ini, bagaimana saya bisa tahu jika pthread_self adalah utas utama (pertama) dalam proses? .

pengembik
sumber
13

Linux menyediakan panggilan sistem seperti itu untuk memungkinkan Anda mendapatkan id dari sebuah utas.

Weiqi Gu
sumber
Sesuai jawaban ini , Anda perlu #include <unistd.h>dan #include <sys/syscall.h>untuk ini.
ComFreek
9

Kamu dapat memakai pthread_self()

Induk mengetahui id utas setelah pthread_create()berhasil dieksekusi, tetapi saat menjalankan utas jika kita ingin mengakses id utas kita harus menggunakan fungsinya pthread_self().

Jeff
sumber
7

Baris tunggal ini memberi Anda pid, setiap threadid dan spid.

nandan
sumber
3

pthread_getthreadid_nptidak ada di Mac os x saya. pthread_tadalah tipe buram. Jangan menyalahkan kepala Anda karenanya. Tetapkan saja void*dan sebut baik. Jika Anda perlu printfmenggunakan %p.


sumber
1
Ya, ini berhasil. Yang saya butuhkan hanyalah mencetaknya untuk debugging sehingga 0x23423423423abcdef sama membantu seperti tid = 1234. Terima kasih!
Qi Fan
3

Saya pikir pertanyaannya tidak hanya tidak jelas tetapi kebanyakan orang juga tidak menyadari perbedaannya. Perhatikan pepatah berikut,

ID utas POSIX tidak sama dengan ID utas yang dikembalikan oleh gettid()panggilan sistem khusus Linux . ID utas POSIX ditetapkan dan dikelola oleh implementasi threading. ID utas yang dikembalikan oleh gettid()adalah angka (mirip dengan ID proses) yang ditetapkan oleh kernel. Meskipun setiap utas POSIX memiliki ID utas kernel unik dalam implementasi penguliran NPTL Linux, aplikasi umumnya tidak perlu mengetahui tentang ID kernel (dan tidak akan portabel jika tergantung pada mengetahuinya).

Dikutip dari: The Linux Programming Interface: A Linux and UNIX System Programming Handbook, Michael Kerrisk

IMHO, hanya ada satu cara portabel yang melewati struktur di mana mendefinisikan variabel memegang nomor secara menaik misalnya 1,2,3... ke per utas. Dengan melakukan ini, id utas dapat dilacak. Meskipun demikian, int pthread_equal(tid1, tid2)fungsi harus digunakan.

snr
sumber
Ini gettid()sebenarnya saran yang bagus, terima kasih! Namun, saya perlu mengikuti jawaban dari Sergey L. di sini: stackoverflow.com/a/21280941/2430526
SRG
1

Ada juga cara lain untuk mendapatkan id utas. Saat membuat utas dengan

int pthread_create(pthread_t * thread, const pthread_attr_t * attr, void * (*start_routine)(void *), void *arg);

panggilan fungsi; parameter pertama pthread_t * threadsebenarnya adalah thread id (yaitu int panjang unsigned yang didefinisikan dalam bits / pthreadtypes.h). Juga, argumen terakhir void *argadalah argumen yang diteruskan ke void * (*start_routine)fungsi yang akan di-thread.

Anda dapat membuat struktur untuk meneruskan beberapa argumen dan mengirim pointer ke struktur.

emre bisa
sumber
-1

Anda juga dapat menulis dengan cara ini dan melakukan hal yang sama. Misalnya:

Program ini menyiapkan array pthread_t dan menghitung jumlah masing-masing. Jadi mencetak jumlah setiap utas dengan id utas.

Pranav Kumar
sumber
Itu tidak menjawab pertanyaan, dan bahkan deskripsi untuk kode itu salah!
U. Windl
-2

Cara yang tidak bergantung platform (mulai dari c ++ 11) adalah:

Oleg Oleg
sumber
ini mungkin tidak "independen platform" seperti yang Anda pikirkan. pada implementasi saya itu memutuskan untuk apthread_t . Di mac itu akan menjadi penunjuk dan di Linux itu bilangan bulat. Ini juga tidak mencerminkan id "asli" yang mungkin Anda lihat topmisalnya. Sesuatu yang harus diperhatikan, tetapi mungkin baik-baik saja untuk beberapa kegunaan.
Brad Allred
1
Di C11 (pertanyaannya tentang C) Anda akan menggunakan thrd_current () dari threads.h
jerry