Trong chương trình linux c, làm thế nào để in id luồng của một luồng được tạo bởi thư viện pthread?
ví dụ: chúng ta có thể nhận được thông tin của một quá trình bằng cáchgetpid()
Trong chương trình linux c, làm thế nào để in id luồng của một luồng được tạo bởi thư viện pthread?
ví dụ: chúng ta có thể nhận được thông tin của một quá trình bằng cáchgetpid()
Câu trả lời:
pthread_self()
hàm sẽ cung cấp id luồng của luồng hiện tại.
pthread_t pthread_self(void);
Các pthread_self()
chức năng trả về xử lý pthread của tiểu trình đang gọi. Hàm pthread_self () KHÔNG trả về luồng tích phân của luồng đang gọi. Bạn phải sử dụng pthread_getthreadid_np()
để trả về một số nhận dạng tích hợp cho luồng.
GHI CHÚ:
pthread_id_np_t tid;
tid = pthread_getthreadid_np();
nhanh hơn đáng kể so với các cuộc gọi này, nhưng cung cấp cùng một hành vi.
pthread_id_np_t tid;
pthread_t self;
self = pthread_self();
pthread_getunique_np(&self, &tid);
pthread_threadid_np
. Tôi đang cần sử dụng cho một dự án, vì vậy cần kiểm tra độ tin cậy của API đó trong nền tảng iOS và OSX. Đã tham khảo liên kết tại opensource.apple.com/source/Libc/Libc-583/pthreads/pthread.h nhưng không chắc liệu chúng có đúng không.
_np
có nghĩa là không di động. Linux có những _np
thứ riêng của nó , nhưng nó không bao gồm Apple pthread_getthreadid_np
.
Gì? Người đó yêu cầu Linux cụ thể và tương đương với getpid (). Không phải BSD hoặc Apple. Câu trả lời là gettid () và trả về một kiểu tích phân. Bạn sẽ phải gọi nó bằng cách sử dụng syscall (), như sau:
#include <sys/types.h>
#include <unistd.h>
#include <sys/syscall.h>
....
pid_t x = syscall(__NR_gettid);
Mặc dù điều này có thể không khả dụng đối với các hệ thống không phải Linux, nhưng threadid có thể so sánh trực tiếp và rất nhanh để có được. Nó có thể được in (chẳng hạn như đối với LOG) giống như một số nguyên bình thường.
getpid()
đã được đưa ra làm ví dụ. Nó không nói rằng ngữ nghĩa là một đặc tả khó. Làm cho mọi người ý thức về việc làm mọi thứ theo cách tương thích với POSIX để các cộng đồng khác ngoài Linux (như FreeBSD, Illumos, OS X, v.v.) có thể hưởng lợi từ chúng không phải là "khoe khoang". Giống như tôi đã nói, tôi đoán Linux đã thực sự trở thành Windows tiếp theo.
Như đã lưu ý trong các câu trả lời khác, pthreads không xác định một cách độc lập với nền tảng để truy xuất ID luồng tích hợp.
Trên hệ thống Linux, bạn có thể nhận được ID luồng do đó:
#include <sys/types.h>
pid_t tid = gettid();
Trên nhiều nền tảng dựa trên BSD, câu trả lời https://stackoverflow.com/a/21206357/316487 này cung cấp một cách không di động.
Tuy nhiên, nếu lý do bạn nghĩ rằng bạn cần ID luồng là để biết liệu bạn đang chạy trên cùng một luồng hay khác luồng với một luồng khác mà bạn kiểm soát, bạn có thể tìm thấy một số tiện ích trong cách tiếp cận này
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");
Nếu bạn chỉ cần biết liệu bạn có đang ở trên chuỗi chính hay không, thì có nhiều cách bổ sung, được ghi lại trong các câu trả lời cho câu hỏi này, làm cách nào để tôi biết pthread_self có phải là chuỗi chính (đầu tiên) trong quy trình hay không? .
pthread_getthreadid_np
không có trên hệ điều hành Mac x của tôi. pthread_t
là một loại không trong suốt. Đừng đập đầu vào nó. Chỉ cần gán cho nó void*
và gọi nó là tốt. Nếu bạn cần printf
sử dụng %p
.
Tôi nghĩ không chỉ câu hỏi không rõ ràng mà hầu hết mọi người cũng không nhận ra sự khác biệt. Kiểm tra câu nói sau đây,
ID luồng POSIX không giống với ID luồng được trả về bởi
gettid()
lệnh gọi hệ thống cụ thể của Linux . ID luồng POSIX được chỉ định và duy trì bởi việc triển khai luồng. ID luồng được trả vềgettid()
là một số (tương tự như ID tiến trình) được chỉ định bởi hạt nhân. Mặc dù mỗi luồng POSIX có một ID luồng nhân duy nhất trong quá trình triển khai luồng NPTL của Linux, một ứng dụng thường không cần biết về các ID nhân (và sẽ không khả dụng nếu nó phụ thuộc vào việc biết chúng).Trích từ: Giao diện Lập trình Linux: Sổ tay Lập trình Hệ thống Linux và UNIX, Michael Kerrisk
IMHO, chỉ có một cách di động để truyền một cấu trúc trong đó xác định một số giữ biến theo cách tăng dần, ví dụ như 1,2,3...
trên mỗi luồng. Bằng cách này, id của chủ đề có thể được theo dõi. Tuy nhiên, int pthread_equal(tid1, tid2)
chức năng nên được sử dụng.
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()
thực sự là một gợi ý tốt, cảm ơn bạn! Tuy nhiên, tôi cần theo dõi câu trả lời của Sergey L. tại đây: stackoverflow.com/a/21280941/2430526
Cũng có một cách khác để lấy id chủ đề. Trong khi tạo chuỗi với
int pthread_create(pthread_t * thread, const pthread_attr_t * attr, void * (*start_routine)(void *), void *arg);
chức năng gọi; tham số đầu tiên pthread_t * thread
thực sự là một id luồng (đó là một int dài không dấu được định nghĩa trong bits / pthreadtypes.h). Ngoài ra, đối số cuối cùng void *arg
là đối số được truyền cho void * (*start_routine)
hàm được phân luồng.
Bạn có thể tạo một cấu trúc để truyền nhiều đối số và gửi một con trỏ đến một cấu trúc.
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
}
Bạn cũng có thể viết theo cách này và nó cũng tương tự. Ví dụ:
for(int i=0;i < total; i++)
{
pthread_join(pth[i],NULL);
cout << "SUM of thread id " << pth[i] << " is " << args[i].sum << endl;
}
Chương trình này thiết lập một mảng pthread_t và tính tổng trên mỗi. Vì vậy, nó đang in ra tổng của mỗi luồng với id luồng.
Cách độc lập với nền tảng (bắt đầu từ c ++ 11) là:
#include <thread>
std::this_thread::get_id();
pthread_t
. Trên mac sẽ là một con trỏ và trên Linux là một số nguyên. Nó cũng không phản ánh id "gốc" mà bạn có thể thấy trong top
ví dụ. Một cái gì đó cần biết, nhưng có thể nó tốt cho một số mục đích sử dụng.