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()
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:
pthread_self()
işlevi mevcut iş parçacığının iş parçacığı kimliğini verecektir.
pthread_t pthread_self(void);
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:
pthread_id_np_t tid;
tid = pthread_getthreadid_np();
bu aramalardan önemli ölçüde daha hızlıdır, ancak aynı davranışı sağlar.
pthread_id_np_t tid;
pthread_t self;
self = pthread_self();
pthread_getunique_np(&self, &tid);
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.
_np
taşınabilir olmayan anlamına gelir. Linux'un kendine ait _np
öğeleri vardır, ancak Apple'ınkini içermez pthread_getthreadid_np
.
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:
#include <sys/types.h>
#include <unistd.h>
#include <sys/syscall.h>
....
pid_t x = syscall(__NR_gettid);
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).
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.
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:
#include <sys/types.h>
pid_t tid = gettid();
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.
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");
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? .
pthread_getthreadid_np
Mac os x'imde değildi. pthread_t
opak bir tiptir. Kafanı ezme. Sadece ona atayın void*
ve iyi deyin. Eğer gerekiyorsa printf
kullanın %p
.
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ğigettid()
, ç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.
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()
aslında iyi bir öneri, teşekkürler! Ancak, Sergey L.'nin cevabını burada takip etmem gerekiyordu: stackoverflow.com/a/21280941/2430526
İş 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 * thread
aslı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.
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
}
Siz de bu şekilde yazabilirsiniz ve o da aynısını yapar. Örneğin:
for(int i=0;i < total; i++)
{
pthread_join(pth[i],NULL);
cout << "SUM of thread id " << pth[i] << " is " << args[i].sum << endl;
}
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.
Platformdan bağımsız yol (c ++ 11'den başlayarak):
#include <thread>
std::this_thread::get_id();
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.