2010-03-03 12 views
53

Có cách nào để đặt tên của một chuỗi trong Linux không?Tôi có thể đặt tên của chuỗi trong pthread/Linux không?

Mục đích chính của tôi là sẽ hữu ích khi gỡ lỗi và cũng tốt nếu tên đó được hiển thị thông qua ví dụ: /proc/$PID/task/$TID/...

+1

Bạn có thể vui lòng cho biết một số ví dụ về cách tên có thể hữu ích khi gỡ lỗi? –

+5

@skwllsp: Vì vậy, bạn có thể dễ dàng xác định chủ đề hơn? –

+1

Tên chủ đề chắc chắn hữu ích khi bạn có các chương trình với một tập hợp lớn các luồng khác nhau, mỗi thao tác cụ thể (như thiết lập đường ống trong đó mỗi luồng thực hiện một phần nhiệm vụ xử lý cho mỗi gói). Tôi đã thấy sự cần thiết cho điều này. Các công cụ gỡ lỗi tốt với nhận thức về hệ điều hành cũng sẽ có thể hiển thị các tên này, không rõ có bao nhiêu trong số các trình gỡ rối hiện có làm điều đó ngày hôm nay. – jakobengblom2

Trả lời

25

Sử dụng chức năng prctl(2) với tùy chọn PR_SET_NAME (xem the docs).

Lưu ý rằng tài liệu hơi khó hiểu. Họ nói

Đặt tên quá trình cho quá trình gọi điện thoại

nhưng vì chủ đề là quá trình trọng lượng nhẹ (LWP) trên Linux, một thread là một quá trình trong trường hợp này.

Bạn có thể thấy tên chủ đề với ps -o cmd hoặc trong /proc/$PID/stat giữa ():

4223 (kjournald) S 1 1 1 0... 
+2

Lưu ý rằng tên luồng thực tế sẽ nằm trong/proc/$ PID/tasks/$ TID/stat – nos

+0

@nos Mặc dù chúng không hiển thị trong danh sách thư mục '/ proc', nhưng các chủ đề có thể truy cập thông qua'/proc/$ TID' (do giống như các quy trình, về cơ bản). – ephemient

+1

@nos, ít nhất là trong phiên bản kernel 3.2.0, đó là '/ proc/$ PID/task/$ TID/stat' (không có s trên tác vụ) –

5

Bạn có thể thực hiện điều này cho mình bằng cách tạo ra một ánh xạ từ điển pthread_t-std::string, và sau đó kết hợp kết quả của pthread_self() với tên mà bạn muốn gán cho chuỗi hiện tại. Lưu ý rằng, nếu bạn làm điều đó, bạn sẽ cần phải sử dụng một mutex hoặc nguyên gốc đồng bộ hóa khác để ngăn chặn nhiều chủ đề đồng thời sửa đổi từ điển (trừ khi thực hiện từ điển của bạn đã làm điều này cho bạn). Bạn cũng có thể sử dụng biến cụ thể theo chủ đề (xem pthread_key_create, pthread_setspecific, pthread_getspecificpthread_key_delete) để lưu tên của chuỗi hiện tại; tuy nhiên, bạn sẽ không thể truy cập tên của các chủ đề khác nếu bạn làm điều đó (trong khi đó, với một từ điển, bạn có thể lặp qua tất cả các cặp id/tên luồng từ bất kỳ chuỗi nào).

+3

Lưu ý rằng giải pháp này là di động trên Linux, Mac OS X và tất cả các hệ thống phù hợp với Đặc điểm kỹ thuật UNIX đơn. (Một đề xuất được đăng bởi Aaron Digulla để sử dụng "prctl" không phải là di động). –

+2

Điều này có vẻ như một ý tưởng thực sự tồi tệ, và mọi người không nên làm điều đó. –

+2

Và làm thế nào bạn có thể nhìn thấy nó từ bên ngoài APP? như trong ps, hay top? – elcuco

89

Kể từ glibc v2.12, bạn có thể sử dụng pthread_setname_nppthread_getname_np để đặt/nhận tên chuỗi.

Các giao diện này có sẵn trên một vài hệ thống POSIX khác (BSD, QNX, Mac) ở các dạng hơi khác nhau.

Thiết tên sẽ được một cái gì đó như thế này:

#include <pthread.h> // or maybe <pthread_np.h> for some OSes 

// Linux 
int pthread_setname_np(pthread_t thread, const char *name); 

// NetBSD: name + arg work like printf(name, arg) 
int pthread_setname_np(pthread_t thread, const char *name, void *arg); 

// FreeBSD & OpenBSD: function name is slightly different, and has no return value 
void pthread_set_name_np(pthread_t tid, const char *name); 

// Mac OS X: must be set from within the thread (can't specify thread ID) 
int pthread_setname_np(const char*); 

Và bạn có thể có được tên mặt sau:

#include <pthread.h> // or <pthread_np.h> ? 

// Linux, NetBSD: 
int pthread_getname_np(pthread_t th, char *buf, size_t len); 
// some implementations don't have a safe buffer (see MKS/IBM below) 
int pthread_getname_np(pthread_t thread, const char **name); 
int pthread_getname_np(pthread_t thread, char *name); 

// FreeBSD & OpenBSD: dont' seem to have getname/get_name equivalent? 
// but I'd imagine there's some other mechanism to read it directly for say gdb 

// Mac OS X: 
int pthread_getname_np(pthread_t, char*, size_t); 

Như bạn có thể thấy nó không phải là hoàn toàn di động giữa các hệ thống POSIX, nhưng như xa như tôi có thể nói qua linux nó phải nhất quán. Ngoài Mac OS X (nơi bạn chỉ có thể làm điều đó từ bên trong chuỗi), các ứng dụng khác ít nhất cũng thích ứng với mã đa nền tảng.

Nguồn:

+0

Tôi không hiểu điểm của 'pthread_set_name_np()' là gì trên BSD nếu tên không thể được truy xuất ...? – kralyk

+0

@kralyk, vâng nó không hữu ích cho việc sử dụng trong ứng dụng, nhưng tôi nghi ngờ nó có thể được lấy thông qua một số cơ chế khác (ví dụ đọc từ bộ nhớ trực tiếp bởi gdb hoặc cái gì?) ... FWIW NetBSD tương thích với các giao diện Linux (và hơi mở rộng chúng bằng cách sử dụng giống như printf) – drfrogsplat

+0

@drfrogsplat - Đâu là hằng số, xác định độ dài tối đa của tên? Tôi không thấy bất kỳ tài liệu nào về nó – HEKTO

Các vấn đề liên quan