linux c प्रोग्राम में pthread की थ्रेड आईडी कैसे प्राप्त करें?


89

लिनक्स सी कार्यक्रम में, थ्रेड लाइब्रेरी द्वारा बनाई गई थ्रेड की थ्रेड आईडी कैसे प्रिंट करें?
पूर्व के लिए: हम एक प्रक्रिया के द्वारा प्राप्त कर सकते हैंgetpid()

जवाबों:


80

pthread_self() फ़ंक्शन वर्तमान थ्रेड की थ्रेड आईडी देगा।

pthread_t pthread_self(void);

pthread_self()फ़ंक्शन बुला धागे की Pthread संभाल। Pthread_self () फ़ंक्शन कॉलिंग थ्रेड के अभिन्न धागे को वापस नहीं करता है। आपको pthread_getthreadid_np()थ्रेड के लिए एक अभिन्न पहचानकर्ता को वापस करने के लिए उपयोग करना चाहिए ।

ध्यान दें:

pthread_id_np_t   tid;
tid = pthread_getthreadid_np();

इन कॉलों की तुलना में काफी तेज है, लेकिन समान व्यवहार प्रदान करता है।

pthread_id_np_t   tid;
pthread_t         self;
self = pthread_self();
pthread_getunique_np(&self, &tid);

37
मूल प्रश्न लिनक्स के बारे में था। लिनक्स में _np फ़ंक्शंस शामिल नहीं हैं। (इसमें उनके मैन पेज शामिल नहीं हैं, मैंने इससे आगे कोई जांच नहीं की।)
ट्रेड-आइडिया फिलिप

pthread_threadid_np OS X> = 10.6 और iOS> = 3.2 पर उपलब्ध है।
21

@ बेलटर क्या आप इसके लिए आधिकारिक दस्तावेज प्रदान कर सकते हैं pthread_threadid_np। एक परियोजना के लिए उपयोग करने की आवश्यकता है, इसलिए iOS और OSX प्लेटफार्मों में उस एपीआई की विश्वसनीयता पर जांच करने की आवश्यकता है। पर लिंक इन्होंने बताया opensource.apple.com/source/Libc/Libc-583/pthreads/pthread.h लेकिन यकीन नहीं यदि वे सही हैं।
विवेक मारन

@Vivek मैं आधिकारिक दस्तावेज़ में किसी भी लिंक, बस हैडर आप लिंक और कम से स्रोत नहीं है opensource.apple.com/source/Libc/Libc-583/pthreads/pthread.c
bleater

9
@ व्यापार- IdeasPhilip - स्पष्ट करने के लिए, _npगैर-पोर्टेबल का मतलब है। लिनक्स का अपना _npसामान है, लेकिन इसमें Apple शामिल नहीं है pthread_getthreadid_np
जोश केली

80

क्या? उस व्यक्ति ने लिनक्स विशिष्ट, और गेटपिड () के बराबर के लिए पूछा। BSD या Apple नहीं। उत्तर गेटटिड () है और एक अभिन्न प्रकार देता है। आपको इसे syscall () का उपयोग करके कॉल करना होगा, जैसे:

#include <sys/types.h>
#include <unistd.h>
#include <sys/syscall.h>

 ....

 pid_t x = syscall(__NR_gettid);

हालांकि यह गैर-लिनक्स सिस्टम के लिए पोर्टेबल नहीं हो सकता है, थ्रेडिड सीधे तुलनीय है और अधिग्रहण के लिए बहुत तेज है। यह सामान्य पूर्णांक की तरह मुद्रित (जैसे कि लॉग के लिए) किया जा सकता है।


9
इसका सही उत्तर होना चाहिए
मैथ्यू एस

उस व्यक्ति ने लिनक्स पर काम करने वाली चीज़ के बारे में पूछा। एक पोर्टेबल तरीके से ऐसा करना मेरे लिए पसंद करने योग्य तरीका है। अगर पोर्टेबिलिटी किसी भी चीज़ के लिए नहीं होती है तो मुझे लगता है कि लिनक्स वास्तव में नया विंडोज बन रहा है ...
जैस्पर सीपकेस

2
@ जैस्पर सीपकेस आप बिंदु को याद कर रहे हैं। उन्होंने एक LINUX कॉल के लिए कहा जो थ्रेड के लिए गेटपिड () के बराबर था। वह गेटिड () है। पोर्टेबिलिटी या POSIX के बारे में सवाल नहीं पूछा। बहुत से लोग सवाल पूछने के बजाय दिखावा और कोशिश करना और सिखाना चाहते हैं। pthread_self () कर्नेल थ्रेड आईडी को वापस नहीं करता है और यह एक तरह से जोड़-तोड़ नहीं करता है जो आसान मुद्रण के लिए बनाता है। इसके अलावा, pthread_self संभवतः एक सूचक है और केवल preadread_equal () के साथ तुलना में, हेरफेर नहीं किया जाना चाहिए। एक आईडी के लिए पूछा गया प्रश्न जिसे आप प्रिंट कर सकते हैं, और वह गेटटीड () है।
इवान लैंग्लोइस

3
@ EvanLanglois वह pthread लाइब्रेरी के साथ काम कर रहा है, जिसका शाब्दिक POSIX थ्रेड लाइब्रेरी है। POSIX संगत उत्तर बनाना अजीब नहीं है। "उन्होंने एक LINUX कॉल के लिए कहा जो थ्रेड के लिए गेटपिड () के बराबर था।" नहीं, getpid()एक उदाहरण के रूप में दिया गया था। यह नहीं कहा कि शब्दार्थ एक कठिन विनिर्देश थे। लोगों को POSIX संगत तरीके से चीजों को करने के लिए जागरूक करना ताकि लिनक्स के अलावा अन्य समुदायों (जैसे FreeBSD, Illumos, OS X, इत्यादि) से फायदा हो सके, उन्हें "दिखावा" नहीं करना चाहिए। जैसा मैंने कहा कि मुझे लगता है कि लिनक्स वास्तव में अगला विंडोज बन गया है।
जैस्पर सीपकेस

14

जैसा कि अन्य उत्तरों में कहा गया है, pthreads एक इंटीग्रल थ्रेड आईडी प्राप्त करने के लिए एक प्लेटफ़ॉर्म-स्वतंत्र तरीके को परिभाषित नहीं करता है।

लिनक्स सिस्टम पर, आप थ्रेड आईडी प्राप्त कर सकते हैं:

#include <sys/types.h>
pid_t tid = gettid();

कई बीएसडी-आधारित प्लेटफार्मों पर, यह उत्तर https://stackoverflow.com/a/21206357/316487 है एक गैर-पोर्टेबल तरीका देता है।

हालाँकि, यदि आपको लगता है कि आपको एक थ्रेड आईडी की आवश्यकता है, तो यह जानने के लिए कि क्या आप उसी या अलग थ्रेड पर चल रहे हैं, जिसे आप नियंत्रित करते हैं, आपको इस दृष्टिकोण में कुछ उपयोगिता मिल सकती है

static pthread_t threadA;

// On thread A...
threadA = pthread_self();

// On thread B...
pthread_t threadB = pthread_self();
if (pthread_equal(threadA, threadB)) printf("Thread B is same as thread A.\n");
else printf("Thread B is NOT same as thread A.\n");

यदि आपको सिर्फ यह जानना है कि क्या आप मुख्य धागे पर हैं, तो अतिरिक्त तरीके हैं, इस प्रश्न के उत्तर में प्रलेखित हैं कि मैं कैसे बता सकता हूं कि क्या pthread_self इस प्रक्रिया में मुख्य (पहला) धागा है?


12
pid_t tid = syscall(SYS_gettid);

लिनक्स आपको थ्रेड की आईडी प्राप्त करने की अनुमति देने के लिए ऐसी प्रणाली कॉल प्रदान करता है।


9

आप उपयोग कर सकते हैं pthread_self()

माता-पिता को थ्रेड आईडी का पता चलने के बाद pthread_create()सस्पेंस से निष्पादित किया जाता है, लेकिन थ्रेड को निष्पादित करते समय यदि हम थ्रेड आईडी का उपयोग करना चाहते हैं तो हमें फ़ंक्शन का उपयोग करना होगा pthread_self()


7

यह सिंगल लाइन आपको पीडड, प्रत्येक थ्रेडिड और स्पिड प्रदान करती है।

 printf("before calling pthread_create getpid: %d getpthread_self: %lu tid:%lu\n",getpid(), pthread_self(), syscall(SYS_gettid));

3

pthread_getthreadid_npमेरे मैक ओएस एक्स पर नहीं था। pthread_tएक अपारदर्शी प्रकार है। इस पर अपना सिर मत मारो। बस इसे असाइन void*करें और इसे अच्छा कहें। यदि आपको printfउपयोग करने की आवश्यकता है %p


1
हां, यह काम करता है। मुझे बस डिबगिंग के लिए प्रिंट करना है, इसलिए 0x23423423423abcdef tid = 1434 के रूप में सहायक है। धन्यवाद!
क्यूई फैन

3

मुझे लगता है कि न केवल यह सवाल स्पष्ट नहीं है, बल्कि अधिकांश लोग अंतर के बारे में भी नहीं जानते हैं। निम्नलिखित कहावत की जाँच करें,

POSIX थ्रेड आईडी लिनक्स विशिष्ट gettid()सिस्टम कॉल द्वारा वापस लौटे थ्रेड आईडी के समान नहीं हैं । POSIX थ्रेड आईडी को थ्रेडिंग कार्यान्वयन द्वारा सौंपा और बनाए रखा जाता है। द्वारा दी गई थ्रेड आईडी gettid()एक संख्या है (प्रोसेस आईडी के समान) जिसे कर्नेल द्वारा असाइन किया गया है। हालाँकि, प्रत्येक POSIX थ्रेड में लिनक्स एनपीटीएल थ्रेडिंग कार्यान्वयन में एक अद्वितीय कर्नेल थ्रेड आईडी है, एक एप्लिकेशन को आम तौर पर कर्नेल आईडी के बारे में जानने की आवश्यकता नहीं होती है (और यह जानने पर निर्भर होने पर पोर्टेबल नहीं होगा)।

इसके अंश: लिनक्स प्रोग्रामिंग इंटरफेस: एक लिनक्स और यूनिक्स सिस्टम प्रोग्रामिंग हैंडबुक, माइकल केरिस्क

आईएमएचओ, केवल एक पोर्टेबल तरीका है जो एक संरचना को पारित करता है जिसमें एक चर होल्डिंग संख्या को आरोही तरीके से परिभाषित किया जाता है जैसे 1,2,3... प्रति धागा। ऐसा करने से, थ्रेड की आईडी को ट्रैक रखा जा सकता है। फिर भी, int pthread_equal(tid1, tid2)फ़ंक्शन का उपयोग किया जाना चाहिए।

if (pthread_equal(tid1, tid2)) printf("Thread 2 is same as thread 1.\n");
else printf("Thread 2 is NOT same as thread 1.\n");

gettid()वास्तव में एक अच्छा सुझाव है, धन्यवाद! हालाँकि, मुझे यहां सेर्गेई एल। के जवाब का पालन करने की आवश्यकता है: 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वास्तव में एक थ्रेड आईडी है (जो कि बिट्स / pthreadtypes.h में परिभाषित एक अहस्ताक्षरित लंबी int है)। इसके अलावा, अंतिम तर्क void *argवह तर्क है जिसे void * (*start_routine)थ्रेडेड करने के लिए कार्य किया जाता है।

आप कई तर्कों को पारित करने के लिए एक संरचना बना सकते हैं और एक संरचना को एक संकेतक भेज सकते हैं।

typedef struct thread_info {
    pthread_t thread;
    //...
} thread_info;
//...
tinfo = malloc(sizeof(thread_info) * NUMBER_OF_THREADS);
//...
pthread_create (&tinfo[i].thread, NULL, handler, (void*)&tinfo[i]);
//...
void *handler(void *targs) {
    thread_info *tinfo = targs;
    // here you get the thread id with tinfo->thread
}

-1

आप इस तरीके से भी लिख सकते हैं और यह वही करता है। उदाहरण के लिए:

for(int i=0;i < total; i++)
{
    pthread_join(pth[i],NULL);
    cout << "SUM of thread id " << pth[i] << " is " << args[i].sum << endl;
}

यह प्रोग्राम pthread_t की एक सरणी सेट करता है और प्रत्येक पर योग की गणना करता है। इसलिए यह थ्रेड आईडी के साथ प्रत्येक थ्रेड के योग को प्रिंट कर रहा है।


यह प्रश्न का उत्तर नहीं देता है, और यहां तक ​​कि कोड के लिए विवरण गलत है!
यू विंडल

-2

प्लेटफ़ॉर्म-स्वतंत्र तरीका (c ++ 11 से शुरू) है:

#include <thread>

std::this_thread::get_id();

यह संभवतः "प्लेटफ़ॉर्म स्वतंत्र" के रूप में नहीं है जैसा कि आप सोचते हैं। मेरे कार्यान्वयन पर यह एक को हल करता है pthread_t। एक मैक पर जो एक पॉइंटर होगा और लिनक्स पर एक पूर्णांक होगा। यह "देशी" आईडी को भी नहीं दर्शाता है जिसे आप topउदाहरण के लिए देख सकते हैं । कुछ के बारे में पता होना चाहिए, लेकिन शायद कुछ उपयोगों के लिए इसका जुर्माना।
ब्रैड ऑलरेड

1
C11 में (प्रश्न C के बारे में था) आप थ्रेड_क्रंट () थ्रेड्स से उपयोग करेंगे ।h
जेरी
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.