Cách tìm id id trong Python


178

Tôi có một chương trình Python đa luồng và một hàm tiện ích writeLog(message), viết ra dấu thời gian theo sau là thông báo. Thật không may, tệp nhật ký kết quả không cho biết luồng nào đang tạo thông báo nào.

Tôi muốn writeLog()có thể thêm một cái gì đó vào tin nhắn để xác định chủ đề nào đang gọi nó. Rõ ràng tôi chỉ có thể làm cho các chủ đề chuyển thông tin này vào, nhưng đó sẽ là công việc nhiều hơn nữa. Có một số chủ đề tương đương os.getpid()mà tôi có thể sử dụng?

Câu trả lời:


226

threading.get_ident()hoạt động hoặc threading.current_thread().ident(hoặc threading.currentThread().identcho Python <2.6).


3
Sửa chữa liên kết của bạn Nicholas. Gần đây tôi nhận ra rằng nếu bạn di chuột qua một tiêu đề trong tài liệu thì một biểu tượng nhỏ màu đỏ xuất hiện ở bên phải. Sao chép + dán để có các liên kết cụ thể hơn đến các tài liệu :-)
Jon Cage

2
Lưu ý rằng nếu bạn đang sử dụng Jython, bạn muốn threading.currentThread()(camelCase, không phải camel_case) như phiên bản 2.5.
Cam Jackson

3
@CharlesAnderson hãy cẩn thận, các tài liệu python trên Thread.name nói "name - Một chuỗi được sử dụng cho mục đích nhận dạng. Nó không có ngữ nghĩa. Nhiều luồng có thể được đặt cùng tên. Tên ban đầu được đặt bởi nhà xây dựng."
drevicko

7
Cũng lưu ý rằng ít nhất trong Python 2.5 và 2.6 trên OS X, dường như có một lỗi threading.current_thread().identkhông phù hợp None. Có lẽ có ý nghĩa khi chỉ sử dụng thread.get_ident()trong Python 2 và threading.current_thread().identtrong Python 3.
Nicholas Riley

5
Các phiên bản trước của câu trả lời của tôi đã đề cập thread.get_ident()( threading.get_ident()đã được thêm vào Python 3.3 - theo các liên kết đến tài liệu).
Nicholas Riley

67

Sử dụng mô-đun ghi nhật ký, bạn có thể tự động thêm định danh luồng hiện tại trong mỗi mục nhật ký. Chỉ cần sử dụng một trong các khóa ánh xạ LogRecord này trong chuỗi định dạng logger của bạn:

% (chủ đề) d: ID chủ đề (nếu có).

% (threadName) s: Tên chủ đề (nếu có).

và thiết lập trình xử lý mặc định của bạn với nó:

logging.basicConfig(format="%(threadName)s:%(message)s")

Tôi đang sử dụng logger. Vì vậy, tôi nghĩ rằng bạn trả lời là giải pháp đơn giản nhất. Nhưng tôi nhận được <concurrent.futures.thread.ThreadPoolExecutor object at 0x7f00f882a438>_2 điều này như là một tên chủ đề. Có phải đó là hai số chủ đề của tôi được gọi
Ravi Shanker Reddy

22

Các thread.get_ident()chức năng trả về một số nguyên dài trên Linux. Nó không thực sự là một chủ đề id.

Tôi sử dụng phương pháp này để thực sự có được id id trên Linux:

import ctypes
libc = ctypes.cdll.LoadLibrary('libc.so.6')

# System dependent, see e.g. /usr/include/x86_64-linux-gnu/asm/unistd_64.h
SYS_gettid = 186

def getThreadId():
   """Returns OS thread id - Specific to Linux"""
   return libc.syscall(SYS_gettid)

Điều này đôi khi có thể được sử dụng nhưng không phải là di động
Piyush Kansal

3
Bạn có thể vui lòng chỉnh sửa câu trả lời này để nó sẽ tiếp tục hữu ích cho khách truy cập nếu liên kết trở nên xấu?
josliber

Làm thế nào để bọc phương thức start () của lớp luồng của tôi để nó có thể lấp đầy self.pid của tôi với nó mỗi khi tôi khởi chạy luồng? Đã thử os.kill (pid) từ bên trong chủ đề riêng, nó chỉ dừng tất cả các chủ đề bao gồm chính, phải được thực hiện bên ngoài bởi cha mẹ, nhưng làm thế nào để có được con đó từ cha mẹ?
Rodrigo Formighieri

Như những người khác đã gợi ý, điều đáng buồn này không hoạt động trên một cái gì đó giống như một linux nhúng chạy trên Arm 32 bit.
Travis Griggs

@TravisGriggs Khái niệm này có thể di chuyển được với Linux, bao gồm các nền tảng ARM 32 bit. Bạn chỉ cần lấy đúng số cuộc gọi hệ thống, có lẽ sẽ là số 224 trên ARM và ARM64. Nó có thể được xác định khi xây dựng hoặc chạy thời gian với một chương trình C nhỏ. Điều này làm việc với tôi với Python 3.7 trên RPi. Câu trả lời của Jake Tesler sẽ tốt hơn nếu bạn có Python 3.8, chưa có trong Raspbian 10.
TrentP


7

Tôi đã thấy các ví dụ về ID luồng như thế này:

class myThread(threading.Thread):
    def __init__(self, threadID, name, counter):
        self.threadID = threadID
        ...

Các tài liệu mô-đun luồng cũng liệt kê namethuộc tính:

...

A thread has a name. 
The name can be passed to the constructor, 
and read or changed through the name attribute.

...

Thread.name

A string used for identification purposes only. 
It has no semantics. Multiple threads may
be given the same name. The initial name is set by the constructor.

7

Bạn có thể nhận được danh tính của luồng đang chạy. Nhận dạng có thể được sử dụng lại cho các luồng khác, nếu luồng hiện tại kết thúc.

Khi bạn gửi một thể hiện của Chủ đề, một tên được đặt ẩn cho chủ đề, đó là mẫu: Số chủ đề

Tên không có ý nghĩa và tên không phải là duy nhất. Nhận dạng của tất cả các chủ đề đang chạy là duy nhất.

import threading


def worker():
    print(threading.current_thread().name)
    print(threading.get_ident())


threading.Thread(target=worker).start()
threading.Thread(target=worker, name='foo').start()

Hàm threading.cien_thread () trả về luồng đang chạy. Đối tượng này giữ toàn bộ thông tin của chủ đề.


0

Tôi đã tạo nhiều luồng trong Python, tôi đã in các đối tượng luồng và tôi đã in id bằng identbiến. Tôi thấy tất cả các id đều giống nhau:

<Thread(Thread-1, stopped 140500807628544)>
<Thread(Thread-2, started 140500807628544)>
<Thread(Thread-3, started 140500807628544)>

4
Tôi đoán nó được tái chế, như các tài liệu cho identtiếng nói: Thread identifiers may be recycled when a thread exits and another thread is created. docs.python.org/2/library/threading.html#threading.Thread.ident
oblalex

0

Tương tự như @brucexin, tôi cần có mã nhận dạng luồng cấp độ hệ điều hành (mà! = thread.get_ident()) Và sử dụng một cái gì đó như dưới đây để không phụ thuộc vào các số cụ thể và chỉ ở mức amd64:

---- 8< ---- (xos.pyx)
"""module xos complements standard module os""" 

cdef extern from "<sys/syscall.h>":                                                             
    long syscall(long number, ...)                                                              
    const int SYS_gettid                                                                        

# gettid returns current OS thread identifier.                                                  
def gettid():                                                                                   
    return syscall(SYS_gettid)                                                                  

---- 8< ---- (test.py)
import pyximport; pyximport.install()
import xos

...

print 'my tid: %d' % xos.gettid()

điều này phụ thuộc vào Cython.


Tôi đã hy vọng đây sẽ là phiên bản đa nền tảng mà tôi đang tìm kiếm, nhưng tôi gặp lỗi về điều này, invalid syntaxcon trỏ sau externtừ khóa. Có cái gì tôi đang thiếu. Điều quan trọng là mã phải nằm trong một mô-đun riêng biệt và có phần mở rộng pyx? Hay đây là một (tái) điều biên dịch?
Travis Griggs

Có, điều này phụ thuộc vào Cython và nên nằm trong một .pyxtệp. Đối với "trăn thuần" có lẽ cũng có thể làm điều gì đó tương tự với ctypes.
kirr
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.