2011-02-01 22 views
7

nền: Tôi đang làm việc trên thư viện ghi nhật ký được nhiều chương trình sử dụng.
Tôi chỉ định tên có thể đọc được cho mỗi chuỗi, chuỗi chính sẽ nhận được "chính", nhưng tôi muốn có thể phát hiện trạng thái đó từ bên trong thư viện mà không yêu cầu mã ở đầu mỗi chính () chức năng.làm cách nào để biết liệu pthread_self có phải là luồng chính (đầu tiên) trong quá trình không?

Cũng lưu ý: Mã thư viện sẽ không luôn được nhập trước tiên từ chuỗi chính.

+0

Làm cách nào để bạn có được tên người khác có thể đọc được? – Potatoswatter

+0

Cụ thể hơn, mô hình mà 'main' không phù hợp là gì? – Potatoswatter

+0

Phần lớn các chủ đề trong hệ thống được bắt đầu chỉ bằng một số cách. Có mã phổ biến ở đó có thể dựa vào một hàm std :: string name() ảo. Các chủ đề chính là khác nhau mặc dù. –

Trả lời

11

Đây là kinda doable, tùy thuộc vào nền tảng mà bạn đang ở trên, nhưng tuyệt đối không trong bất kỳ cách cầm tay và generic ...

Mac OS X dường như là người duy nhất với một cách tiếp cận trực tiếp và ghi nhận, theo pthread.h tập tin của họ:

/* returns non-zero if the current thread is the main thread */ 
int pthread_main_np(void); 

tôi cũng thấy rằng FreeBSD có một tiêu đề pthread_np.h định nghĩa pthread_main_np(), vì thế này nên làm việc trên FreeBSD quá (8.1 ít nhất), và OpenBSD (4.8 ít nhất) có pthread_main_np() được định nghĩa trong pthread.h. Lưu ý rằng _np rõ ràng là viết tắt của không di động!

Nếu không, cách tiếp cận "chung" duy nhất mà bạn nghĩ đến là so sánh PID của quy trình với TID của chuỗi hiện tại, nếu chúng khớp nhau, luồng đó là chính. Điều này không nhất thiết phải hoạt động trên tất cả các nền tảng, nó phụ thuộc vào việc bạn có thực sự có được TID hay không (ví dụ: bạn không thể sử dụng OpenBSD), và nếu có, nếu có bất kỳ mối quan hệ nào với PID hoặc hệ thống con luồng có kế toán riêng của nó mà không nhất thiết liên quan.

Tôi cũng nhận thấy rằng một số nền tảng trả lại giá trị không đổi như TID cho chuỗi chính, vì vậy bạn chỉ có thể kiểm tra các giá trị đó.

Một bản tóm tắt ngắn gọn về nền tảng Tôi đã kiểm tra:

  • Linux: thể đây, syscall (SYS_gettid) == getpid() là những gì bạn muốn
  • FreeBSD: không thể thực hiện ở đây, thr_self() có vẻ ngẫu nhiên và không có liên quan đến getpid()
  • OpenBSD: không thể thực hiện ở đây, không có cách nào để có được một TID
  • NetBSD: thể đây, _lwp_self() luôn trả về 1 cho m ain chủ đề
  • Solaris: thể đây, pthread_self() luôn trả về 1 đối với các chủ đề chính

Vì vậy, về cơ bản bạn sẽ có thể làm điều đó trực tiếp trên Mac OS X, FreeBSD và OpenBSD.

Bạn có thể sử dụng phương pháp TID == PID trên Linux.

Bạn có thể sử dụng phương pháp TID == 1 trên NetBSD và Solaris.

Tôi hy vọng điều này sẽ giúp bạn có một ngày tốt lành!

+1

MacOSX có nguồn gốc mạnh mẽ trong * Loại BSD giải thích khi sử dụng 'pthread_main_np()'. Đó là một giao diện đầy đủ tài liệu (có một manpage) trên tất cả các * BSDs là tốt. Solaris có tương đương với 'thr_main()' và bạn có thể chỉ đơn giản là '#define pthread_main_np thr_main' ở đó. Sử dụng tốt hơn so với mẹo 'TID == 1'. –

+1

Điều này có thể không nói, nhưng nếu bạn cũng có kế hoạch viết cho iOS, hàm pthread_main_np() cũng được hỗ trợ. – NSDestr0yer

7

Gọi pthread_self() từ main() và ghi lại kết quả. So sánh các cuộc gọi trong tương lai với pthread_self() với giá trị được lưu trữ của bạn để biết liệu bạn có đang ở trên chuỗi chính hay không.

+1

Tôi đã chỉnh sửa câu hỏi của mình để làm rõ rằng thư viện này được các chương trình MANY sử dụng. Thêm mã mới vào mỗi và mọi mã đều không mong muốn. –

0

Bạn có thể sử dụng một số loại tài nguyên tên được chia sẻ cho phép các chủ đề sinh sản để đăng ký tên (có thể là bản đồ của id luồng để đặt tên). Sau đó, hệ thống ghi nhật ký của bạn có thể đặt một cuộc gọi vào một phương thức nhận tên thông qua ID luồng theo cách an toàn.

Khi chuỗi chết, hãy xóa tên khỏi bản đồ để tránh rò rỉ bộ nhớ.

Phương pháp này nên cho phép tất cả các chuỗi được đặt tên chứ không chỉ chính.

+0

Tôi đã có tất cả điều này. Điều này không giúp xác định tự động luồng nào là chính. –

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