làm thế nào để lấy id luồng của một pthread trong chương trình linux c?


89

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:


80

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);

37
Câu hỏi ban đầu là về Linux. Linux không bao gồm các hàm _np. (Nó không bao gồm các trang người đàn ông của họ, tôi không kiểm tra thêm nữa.)
Trade-Ideas Philip

pthread_threadid_np khả dụng trên OS X> = 10.6 và iOS> = 3.2.
bleater

@Bleater Bạn có thể vui lòng cung cấp tài liệu chính thức cho 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.
Vivek Maran

@Vivek Tôi không có bất kỳ liên kết nào đến tài liệu chính thức, chỉ có tiêu đề bạn liên kết và nguồn tại opensource.apple.com/source/Libc/Libc-583/pthreads/pthread.c
bleater 27/02/15

9
@ Trade-IdeasPhilip - Để làm rõ, _npcó nghĩa là không di động. Linux có những _npthứ riêng của nó , nhưng nó không bao gồm Apple pthread_getthreadid_np.
Josh Kelley

80

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.


9
Điều này cần được câu trả lời đúng
Matthew S

Người đó hỏi về một thứ hoạt động trên Linux. Đối với tôi, làm như vậy một cách di động dường như là cách tốt hơn để làm điều đó. Nếu tính di động không được tính cho bất cứ điều gì sau đó tôi đoán Linux thực sự trở thành Windows mới ...
Jasper Siepkes

2
@Jasper Siepkes Bạn đang thiếu điểm. Anh ta yêu cầu một lệnh gọi LINUX tương đương với getpid () cho các luồng. Đó là gettid (). Câu hỏi không hỏi về tính di động hoặc POSIX. Có quá nhiều người muốn thể hiện và thử dạy hơn là đặt câu hỏi như đã hỏi. pthread_self () không trả về id luồng nhân và nó không thể thao tác theo cách giúp in dễ dàng. Ngoài ra, pthread_self có thể là một con trỏ và không nên được thao tác, chỉ được so sánh với pthread_equal (). Câu hỏi yêu cầu một ID mà bạn có thể in, và đó là gettid ().
Evan Langlois

3
@EvanLanglois Anh ấy đang làm việc với thư viện pthread, nghĩa đen là thư viện luồng POSIX. Tạo một câu trả lời tương thích với POSIX không phải là điều kỳ lạ. "Anh ấy đã yêu cầu một lệnh gọi LINUX tương đương với getpid () cho các luồng." Khô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.
Jasper Siepkes

14

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? .


12
pid_t tid = syscall(SYS_gettid);

Linux cung cấp lệnh gọi hệ thống như vậy để cho phép bạn lấy id của một luồng.


9

Bạn có thể dùng pthread_self()

Cha mẹ sẽ biết id luồng sau khi pthread_create()thực thi thành công, nhưng trong khi thực thi luồng, nếu chúng ta muốn truy cập id luồng, chúng ta phải sử dụng hàm pthread_self().


7

Dòng đơn này cung cấp cho bạn pid, từng threadid và spid.

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

3

pthread_getthreadid_npkhông có trên hệ điều hành Mac x của tôi. pthread_tlà 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 printfsử dụng %p.


1
Vâng, điều này hoạt động. Tất cả những gì tôi cần là in nó để gỡ lỗi vì vậy 0x23423423423abcdef cũng hữu ích như tid = 1234. Cảm ơn bạn!
Qi Fan,

3

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");

Đây 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
SRG

1

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 * threadthự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 *arglà đố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
}

-1

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.


Nó không trả lời câu hỏi, và ngay cả mô tả cho mã cũng sai!
U. Windl

-2

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();

điều này có lẽ không phải là "nền tảng độc lập" như bạn nghĩ. trong quá trình thực hiện của tôi, nó giải quyết thành a 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 topví 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.
Brad Allred

1
Trong C11 (các câu hỏi về C), bạn sẽ sử dụng thrd_current () từ threads.h
jerry
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.