linux c programında bir pthread'in iş parçacığı kimliği nasıl alınır?


94

Linux c programında, pthread kütüphanesi tarafından oluşturulan bir evrenin evre kimliği nasıl yazdırılır?
örneğin: bir sürecin pid'ini şu şekilde alabilirizgetpid()

Yanıtlar:


81

pthread_self() işlevi mevcut iş parçacığının iş parçacığı kimliğini verecektir.

pthread_self()Fonksiyon çağrılan evrenin pthread tanıtıcısı döndürür. Pthread_self () işlevi çağıran evrenin integral evresini döndürmez. İş pthread_getthreadid_np()parçacığı için bir integral tanımlayıcı döndürmek için kullanmanız gerekir .

NOT:

bu aramalardan önemli ölçüde daha hızlıdır, ancak aynı davranışı sağlar.


38
Asıl soru Linux hakkındaydı. Linux, _np işlevlerini içermez. (Kılavuz sayfalarını içermiyor, bundan daha fazlasını kontrol etmedim.)
Ticaret-Fikirler Philip

pthread_threadid_np, OS X> = 10.6 ve iOS> = 3.2'de mevcuttur.
2014

@Bleater için resmi belgeleri sağlayabilir misiniz pthread_threadid_np? Bir proje için kullanmam gerekiyor, bu yüzden iOS ve OSX platformlarında bu API'nin güvenilirliğini kontrol etmeniz gerekiyor. Opensource.apple.com/source/Libc/Libc-583/pthreads/pthread.h adresindeki bağlantıya atıfta bulunuldu, ancak bunların doğru olup olmadıklarından emin değilim.
Vivek Maran

@Vivek Resmi belgelere herhangi bir bağlantım yok, sadece bağladığınız başlık ve opensource.apple.com/source/Libc/Libc-583/pthreads/pthread.c
bleater

10
@ Trade-IdeasPhilip - Açıklamak gerekirse, _nptaşınabilir olmayan anlamına gelir. Linux'un kendine ait _npöğeleri vardır, ancak Apple'ınkini içermez pthread_getthreadid_np.
Josh Kelley

85

Ne? Kişi Linux'a özel ve getpid () eşdeğerini istedi. BSD veya Apple değil. Cevap gettid () 'dır ve bir integral türü döndürür. Syscall () kullanarak çağırmanız gerekecek, örneğin:

Bu, linux olmayan sistemlere taşınabilir olmasa da, iş parçacığı doğrudan karşılaştırılabilir ve elde edilmesi çok hızlıdır. Normal bir tamsayı gibi yazdırılabilir (örneğin LOG'lar için).


11
Bu doğru cevap olmalı
Matthew S

Kişi, Linux'ta çalışan bir şey sordu. Bunu taşınabilir bir şekilde yapmak, bana bunu yapmanın tercih edilen yolu gibi görünüyor. Taşınabilirlik hiçbir şey için geçerli değilse, sanırım Linux gerçekten yeni Windows oluyor ...
Jasper Siepkes

3
@Jasper Siepkes Noktayı kaçırıyorsunuz. İş parçacıkları için getpid () ile eşdeğer bir LINUX çağrısı istedi. Bu gettid (). Soru taşınabilirlik veya POSIX hakkında sorulmadı. Çok fazla insan soruyu sorulduğu gibi sormak yerine gösteriş yapmak ve öğretmek ister. pthread_self () çekirdek iş parçacığı kimliğini döndürmez ve yazdırmayı kolaylaştıracak şekilde değiştirilemez. Ayrıca, pthread_self büyük olasılıkla bir göstericidir ve manipüle edilmemelidir, sadece pthread_equal () ile karşılaştırıldığında. Soru yazdırabileceğiniz bir kimlik sordu ve bu gettid ().
Evan Langlois

3
@EvanLanglois pthread kitaplığı, kelimenin tam anlamıyla POSIX iş parçacığı kitaplığı ile çalışıyor. POSIX uyumlu bir yanıt vermek o kadar da tuhaf değil. "İş parçacıkları için getpid () ile eşdeğer bir LINUX çağrısı istedi." Hayır, getpid()örnek olarak verilmiştir. Anlambilimin zor bir özellik olduğunu söylemedi. Linux dışındaki diğer toplulukların (FreeBSD, Illumos, OS X, vb.) Onlardan yararlanabilmesi için insanları POSIX uyumlu bir şekilde yaptıklarının farkında kılmak "gösteriş yapmak" değildir. Dediğim gibi, sanırım Linux gerçekten bir sonraki Windows oldu.
Jasper Siepkes

14

Diğer yanıtlarda belirtildiği gibi, pthreads bir integral iş parçacığı kimliğini almak için platformdan bağımsız bir yol tanımlamaz.

Linux sistemlerinde, iş parçacığı kimliğini şu şekilde alabilirsiniz:

Birçok BSD tabanlı platformda bu yanıt https://stackoverflow.com/a/21206357/316487 taşınabilir olmayan bir yol sağlar.

Bununla birlikte, bir iş parçacığı kimliğine ihtiyacınız olduğunu düşünmenizin nedeni, kontrol ettiğiniz başka bir iş parçacığı için aynı veya farklı iş parçacığı üzerinde çalışıp çalışmadığınızı bilmekse, bu yaklaşımda bir yardımcı program bulabilirsiniz.

Sadece ana iş parçacığında olup olmadığınızı bilmeniz gerekiyorsa, bu sorunun yanıtlarında belgelenen ek yollar vardır, işlemdeki ana (ilk) iş parçacığı pthread_self olup olmadığını nasıl anlarım? .


13

Linux, bir iş parçacığının kimliğini almanıza izin vermek için böyle bir sistem çağrısı sağlar.


Gereğince bu cevap , size gereken #include <unistd.h>ve #include <sys/syscall.h>bunun için.
ComFreek

9

Kullanabilirsiniz pthread_self()

Üst pthread_create()öğe, başarılı bir şekilde çalıştırıldıktan sonra evre kimliğini öğrenir, ancak evreyi yürütürken, evre kimliğine erişmek istiyorsak, işlevi kullanmalıyız pthread_self().


7

Bu tek satır size pid, her bir threadid ve spid verir.


3

pthread_getthreadid_npMac os x'imde değildi. pthread_topak bir tiptir. Kafanı ezme. Sadece ona atayın void*ve iyi deyin. Eğer gerekiyorsa printfkullanın %p.


1
Evet, bu çalışıyor. Tek ihtiyacım olan, hata ayıklama için yazdırmak, böylece 0x23423423423abcdef tid = 1234 kadar yardımcı olur. Teşekkür ederim!
Qi Fan

3

Bence sadece soru net değil, aynı zamanda çoğu insan da farkın farkında değil. Şu sözü inceleyin,

POSIX iş parçacığı kimlikleri, Linux'a özgü gettid()sistem çağrısı tarafından döndürülen iş parçacığı kimlikleri ile aynı değildir . POSIX iş parçacığı kimlikleri, evreleme uygulaması tarafından atanır ve korunur. Tarafından döndürülen iş parçacığı kimliği gettid(), çekirdek tarafından atanan bir sayıdır (işlem kimliğine benzer).Her bir POSIX iş parçacığı, Linux NPTL iş parçacığı uygulamasında benzersiz bir çekirdek iş parçacığı kimliğine sahip olsa da, bir uygulamanın genellikle çekirdek kimliklerini bilmesine gerek yoktur (ve bilmesine bağlıysa taşınabilir olmayacaktır).

Alıntı: Linux Programlama Arayüzü: Bir Linux ve UNIX Sistem Programlama El Kitabı, Michael Kerrisk

IMHO, değişken tutma sayılarını artan bir şekilde, örneğin 1,2,3... her bir iş parçacığına tanımlayan bir yapıyı geçirmenin yalnızca bir taşınabilir yolu vardır . Bunu yaparak, konuların kimliği takip edilebilir. Yine de int pthread_equal(tid1, tid2)işlev kullanılmalıdır.


Bu gettid()aslında iyi bir öneri, teşekkürler! Ancak, Sergey L.'nin cevabını burada takip etmem gerekiyordu: stackoverflow.com/a/21280941/2430526
SRG

1

İş parçacığı kimliği almanın başka bir yolu da var. İle konu oluştururken

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

işlev çağrısı; ilk parametre pthread_t * threadaslında bir evre kimliğidir (bu, bit / pthreadtypes.h içinde tanımlanan bir işaretsiz uzun int'dir). Ayrıca, son argüman void *arg, iletilen argümandır. void * (*start_routine) iş parçacığı oluşturulacak işleve .

Birden çok argümanı iletmek ve bir yapıya bir işaretçi göndermek için bir yapı oluşturabilirsiniz.


-1

Siz de bu şekilde yazabilirsiniz ve o da aynısını yapar. Örneğin:

Bu program bir pthread_t dizisi kurar ve her birinde toplamı hesaplar. Böylece her bir iş parçacığının toplamını iş parçacığı kimliği ile yazdırıyor.


Soruya cevap vermiyor ve hatta kodun açıklaması bile yanlış!
U. Windl

-2

Platformdan bağımsız yol (c ++ 11'den başlayarak):


bu muhtemelen sizin düşündüğünüz kadar "platformdan bağımsız" değildir. benim uygulamamda a pthread_t. Mac'te işaretçi ve Linux'ta bir tamsayı olacak. Ayrıca, topörneğin içinde görebileceğiniz "yerel" kimliği de yansıtmaz . Dikkat edilmesi gereken bir şey, ancak bazı kullanımlar için sorun olmayabilir.
Brad Allred

1
C11'de (soru C hakkındaydı) thread.h'den thrd_current () kullanırdınız
jerry
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.