จะรับ id เธรดของ pthread ในโปรแกรม linux c ได้อย่างไร


94

ในโปรแกรม linux c วิธีพิมพ์ thread id ของเธรดที่สร้างโดย pthread library?
เช่น: เราสามารถรับ pid ของกระบวนการโดยgetpid()

คำตอบ:


81

pthread_self() ฟังก์ชันจะให้รหัสเธรดของเธรดปัจจุบัน

pthread_self()ฟังก์ชันส่งกลับจับ pthread ของด้ายโทร ฟังก์ชัน pthread_self () ไม่ส่งคืนอินทิกรัลเธรดของเธรดการเรียกใช้ คุณต้องใช้pthread_getthreadid_np()เพื่อส่งคืนตัวระบุอินทิกรัลสำหรับเธรด

บันทึก:

เร็วกว่าการโทรเหล่านี้อย่างมาก แต่มีลักษณะการทำงานเหมือนกัน


38
คำถามเดิมเกี่ยวกับ Linux Linux ไม่มีฟังก์ชัน _np (ไม่รวมถึงหน้าคนของพวกเขาฉันไม่ได้ตรวจสอบเพิ่มเติมมากกว่านั้น)
Trade-Ideas Philip

pthread_threadid_np พร้อมใช้งานบน OS X> = 10.6 และ iOS> = 3.2
bleater

@Bleater คุณกรุณาให้เอกสารอย่างเป็นทางการสำหรับpthread_threadid_np. จำเป็นต้องใช้สำหรับโปรเจ็กต์ดังนั้นจำเป็นต้องตรวจสอบความน่าเชื่อถือของ API นั้นในแพลตฟอร์ม iOS และ OSX อ้างอิงลิงค์ที่opensource.apple.com/source/Libc/Libc-583/pthreads/pthread.hแต่ไม่แน่ใจว่าเป็นลิงค์ที่ถูกต้องหรือไม่
วิเวกมาราน

@Vivek ฉันไม่มีลิงก์ไปยังเอกสารอย่างเป็นทางการเพียงแค่ส่วนหัวที่คุณลิงก์และแหล่งที่มาที่opensource.apple.com/source/Libc/Libc-583/pthreads/pthread.c
bleater

10
@ Trade-IdeasPhilip - เพื่อความชัดเจน_npหมายถึงไม่พกพา ลินุกซ์มีของตัวเอง_npสิ่งที่ pthread_getthreadid_npแต่จะไม่รวมถึงแอปเปิ้ล
Josh Kelley

85

อะไร? บุคคลนั้นขอเฉพาะ Linux และเทียบเท่ากับ getpid () ไม่ใช่ BSD หรือ Apple คำตอบคือ gettid () และส่งกลับประเภทอินทิกรัล คุณจะต้องเรียกมันโดยใช้ syscall () ดังนี้:

แม้ว่าสิ่งนี้อาจไม่สามารถพกพาไปยังระบบที่ไม่ใช่ linux ได้ แต่ threadid นั้นเทียบได้โดยตรงและรวดเร็วมากในการรับ สามารถพิมพ์ได้ (เช่นสำหรับ LOG) เหมือนจำนวนเต็มปกติ


11
นี่น่าจะเป็นคำตอบที่แท้จริง
Matthew S

บุคคลนั้นถามเกี่ยวกับบางสิ่งที่ทำงานบน Linux การทำเช่นนี้ในแบบพกพาดูเหมือนว่าฉันจะเป็นวิธีที่ดีกว่า หากการพกพาไม่นับรวมกับสิ่งใด ๆ ฉันเดาว่า Linux กำลังกลายเป็น Windows ใหม่จริงๆ ...
Jasper Siepkes

3
@Jasper Siepkes คุณกำลังพลาดประเด็น เขาขอการเรียก LINUX ที่เทียบเท่ากับ getpid () สำหรับเธรด นั่นคือ gettid () คำถามไม่ได้ถามเกี่ยวกับการพกพาหรือ POSIX มีคนจำนวนมากเกินไปที่อยากอวดและพยายามสอนแทนที่จะถามคำถามตามที่ถาม pthread_self () ไม่ส่งคืนรหัสเคอร์เนลเธรดและไม่สามารถปรับเปลี่ยนได้ในลักษณะที่ทำให้พิมพ์ได้ง่าย นอกจากนี้ pthread_self ยังน่าจะเป็นตัวชี้และไม่ควรถูกปรับแต่งโดยเปรียบเทียบกับ pthread_equal () เท่านั้น คำถามถามหา ID ที่คุณพิมพ์ได้และนั่นคือ gettid ()
Evan Langlois

3
@EvanLanglois เขาทำงานกับไลบรารี pthread ซึ่งเป็นไลบรารีเธรด POSIX การทำคำตอบที่เข้ากันได้กับ POSIX ไม่ใช่เรื่องแปลก "เขาขอการเรียก LINUX ที่เทียบเท่ากับ getpid () สำหรับเธรด" ไม่getpid()ได้ให้เป็นตัวอย่าง มันไม่ได้บอกว่าความหมายเป็นข้อกำหนดที่ยาก การทำให้ผู้คนตระหนักถึงการทำสิ่งต่างๆด้วยวิธีที่เข้ากันได้กับ POSIX ดังนั้นชุมชนอื่น ๆ นอกเหนือจาก Linux (เช่น FreeBSD, Illumos, OS X ฯลฯ ) จะได้รับประโยชน์จากสิ่งเหล่านี้ไม่ใช่การ "อวด" อย่างที่ฉันบอกว่าฉันเดาว่า Linux กลายเป็น Windows ตัวต่อไปแล้ว
Jasper Siepkes

14

ดังที่ระบุไว้ในคำตอบอื่น ๆ pthreads ไม่ได้กำหนดวิธีที่ไม่ขึ้นกับแพลตฟอร์มในการดึง ID เธรดอินทิกรัล

บนระบบ Linux คุณสามารถรับ thread ID ได้ดังนี้:

บนแพลตฟอร์มที่ใช้ BSD จำนวนมากคำตอบนี้https://stackoverflow.com/a/21206357/316487เป็นวิธีที่ไม่พกพา

อย่างไรก็ตามหากเหตุผลที่คุณคิดว่าคุณต้องการ ID เธรดคือการทราบว่าคุณกำลังรันบนเธรดเดียวกันหรือต่างกันกับเธรดอื่นที่คุณควบคุมคุณอาจพบยูทิลิตี้บางอย่างในแนวทางนี้

หากคุณต้องการทราบว่าคุณอยู่ในเธรดหลักหรือไม่มีวิธีเพิ่มเติมซึ่งบันทึกไว้ในคำตอบสำหรับคำถามนี้ฉันจะทราบได้อย่างไรว่า pthread_self เป็นเธรดหลัก (ตัวแรก) ในกระบวนการหรือไม่ .


13

Linux จัดเตรียมการเรียกระบบดังกล่าวเพื่อให้คุณได้รับ id ของเธรด


ตามคำตอบนี้คุณต้องการ#include <unistd.h>และ#include <sys/syscall.h>สำหรับสิ่งนี้
ComFreek

9

คุณสามารถใช้ได้ pthread_self()

ผู้ปกครองได้รับทราบด้าย id หลังจากที่pthread_create()ถูกดำเนินการสำเร็จ แต่ในขณะที่การดำเนินด้ายถ้าเราต้องการที่จะเข้าถึงด้าย id pthread_self()ที่เราต้องใช้ฟังก์ชั่น


7

บรรทัดเดียวนี้ให้ pid แต่ละ threadid และ spid


3

pthread_getthreadid_npไม่ได้อยู่บน Mac os x ของฉัน pthread_tเป็นชนิดทึบแสง อย่าทุบหัวของคุณ เพียงแค่กำหนดให้void*และเรียกว่าดี หากคุณจำเป็นต้องใช้ printf%p


1
ใช่มันใช้งานได้ สิ่งที่ฉันต้องการคือพิมพ์เพื่อดีบั๊กดังนั้น 0x23423423423abcdef จึงมีประโยชน์เท่ากับ tid = 1234 ขอขอบคุณ!
Qi Fan

3

ฉันคิดว่าไม่เพียง แต่คำถามจะไม่ชัดเจน แต่คนส่วนใหญ่ยังไม่ตระหนักถึงความแตกต่าง ตรวจสอบคำพูดต่อไปนี้

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

ตัดตอนมาจาก: ส่วนต่อประสานการเขียนโปรแกรม Linux: คู่มือการเขียนโปรแกรมระบบ Linux และ UNIX, Michael Kerrisk

IMHO มีวิธีแบบพกพาเพียงวิธีเดียวที่ส่งผ่านโครงสร้างที่กำหนดตัวแปรการถือครองตัวเลขในลักษณะจากน้อยไปมากเช่น1,2,3... ต่อเธรด การทำเช่นนี้จะสามารถติดตาม id ของเธรดได้ อย่างไรก็ตามint pthread_equal(tid1, tid2)ควรใช้ฟังก์ชัน


gettid()เป็นจริงเป็นคำแนะนำที่ดีขอขอบคุณ! อย่างไรก็ตามฉันต้องทำตามคำตอบของ Sergey L. ที่นี่: stackoverflow.com/a/21280941/2430526
SRG

1

นอกจากนี้ยังมีอีกวิธีหนึ่งในการรับรหัสเธรด ขณะสร้างเธรดด้วย

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

การเรียกใช้ฟังก์ชัน; พารามิเตอร์แรกpthread_t * threadคือ id เธรด (นั่นคือ int long ที่ไม่ได้ลงชื่อที่กำหนดไว้ในบิต / pthreadtypes.h) นอกจากนี้อาร์กิวเมนต์สุดท้ายvoid *argคืออาร์กิวเมนต์ที่ถูกส่งไปยัง void * (*start_routine)ฟังก์ชันที่จะเป็นเธรด

คุณสามารถสร้างโครงสร้างเพื่อส่งผ่านหลายอาร์กิวเมนต์และส่งตัวชี้ไปยังโครงสร้าง


-1

คุณสามารถเขียนในลักษณะนี้ได้เช่นกัน เช่น:

โปรแกรมนี้ตั้งค่าอาร์เรย์ของ pthread_t และคำนวณผลรวมของแต่ละรายการ ดังนั้นจึงเป็นการพิมพ์ผลรวมของแต่ละเธรดด้วยรหัสเธรด


มันไม่ตอบคำถามและแม้แต่คำอธิบายรหัสก็ผิด!
U. Windl

-2

วิธีที่ไม่ขึ้นกับแพลตฟอร์ม (เริ่มจาก c ++ 11) คือ:


สิ่งนี้อาจไม่ได้เป็น "แพลตฟอร์มอิสระ" อย่างที่คุณคิด ในการใช้งานของฉันมันแก้ไขเป็นpthread_tไฟล์. บน Mac ที่จะเป็นตัวชี้และบน Linux เป็นจำนวนเต็ม นอกจากนี้ยังไม่แสดงรหัส "เนทีฟ" ที่คุณอาจเห็นtopตัวอย่างเช่น สิ่งที่ควรระวัง แต่อาจใช้ได้ดีสำหรับการใช้งานบางอย่าง
Brad Allred

1
ใน C11 (คำถามเกี่ยวกับ C) คุณจะใช้ thrd_current () จาก threads.h
jerry
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.