Python chọn ví dụ thăm dò ý kiến

Mô-đun được chọn cung cấp quyền truy cập vào các chức năng giám sát I/O dành riêng cho nền tảng. Giao diện di động nhất là chức năng POSIX select(), có sẵn trên Unix và Windows. Mô-đun này cũng bao gồm thăm dò (), API chỉ dành cho Unix và một số tùy chọn chỉ hoạt động với các biến thể cụ thể của Unix

lựa chọn()

Hàm select() của Python là một giao diện trực tiếp để triển khai hệ điều hành cơ bản. Nó giám sát ổ cắm, tệp đang mở và đường dẫn (bất kỳ thứ gì có phương thức fileno() trả về bộ mô tả tệp hợp lệ) cho đến khi chúng có thể đọc hoặc ghi được hoặc xảy ra lỗi giao tiếp. select() giúp việc giám sát nhiều kết nối cùng lúc trở nên dễ dàng hơn và hiệu quả hơn so với việc viết một vòng lặp bỏ phiếu trong Python bằng cách sử dụng thời gian chờ của ổ cắm, bởi vì việc giám sát diễn ra trong lớp mạng của hệ điều hành, thay vì trình thông dịch

Ghi chú

Sử dụng các đối tượng tệp của Python với select() hoạt động cho Unix, nhưng không được hỗ trợ trong Windows

Ví dụ máy chủ echo từ phần ổ cắm có thể được mở rộng để theo dõi nhiều kết nối cùng một lúc bằng cách sử dụng select(). Phiên bản mới bắt đầu bằng cách tạo một ổ cắm TCP/IP không chặn và định cấu hình nó để nghe trên một địa chỉ

import select
import socket
import sys
import Queue

# Create a TCP/IP socket
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.setblocking(0)

# Bind the socket to the port
server_address = ('localhost', 10000)
print >>sys.stderr, 'starting up on %s port %s' % server_address
server.bind(server_address)

# Listen for incoming connections
server.listen(5)

Các đối số để chọn () là ba danh sách chứa các kênh liên lạc để giám sát. Đầu tiên là danh sách các đối tượng được kiểm tra để đọc dữ liệu đến, đối tượng thứ hai chứa các đối tượng sẽ nhận dữ liệu gửi đi khi có chỗ trong bộ đệm của chúng và đối tượng thứ ba có thể có lỗi (thường là sự kết hợp của . Bước tiếp theo trong máy chủ là thiết lập danh sách chứa nguồn đầu vào và đích đầu ra sẽ được chuyển đến select()

# Sockets from which we expect to read
inputs = [ server ]

# Sockets to which we expect to write
outputs = [ ]

Các kết nối được thêm vào và xóa khỏi các danh sách này bởi vòng lặp chính của máy chủ. Vì phiên bản này của máy chủ sẽ đợi một ổ cắm có thể ghi được trước khi gửi bất kỳ dữ liệu nào (thay vì gửi trả lời ngay lập tức), mỗi kết nối đầu ra cần một hàng đợi để hoạt động như một bộ đệm cho dữ liệu được gửi qua nó.

# Outgoing message queues (socket:Queue)
message_queues = {}

Phần chính của chương trình máy chủ lặp lại, gọi select() để chặn và chờ hoạt động mạng

while inputs:

    # Wait for at least one of the sockets to be ready for processing
    print >>sys.stderr, '\nwaiting for the next event'
    readable, writable, exceptional = select.select(inputs, outputs, inputs)

select() trả về ba danh sách mới, chứa các tập hợp con nội dung của danh sách được truyền vào. Tất cả các ổ cắm trong danh sách có thể đọc được đều có dữ liệu đến được lưu vào bộ đệm và có sẵn để đọc. Tất cả các ổ cắm trong danh sách có thể ghi đều có dung lượng trống trong bộ đệm của chúng và có thể được ghi vào. Ổ cắm được trả về trong trường hợp ngoại lệ đã xảy ra lỗi (định nghĩa thực tế về "tình trạng ngoại lệ" tùy thuộc vào nền tảng)

Ổ cắm “có thể đọc được” đại diện cho ba trường hợp có thể xảy ra. Nếu ổ cắm là ổ cắm “máy chủ” chính, ổ cắm được sử dụng để lắng nghe các kết nối, thì điều kiện “có thể đọc được” có nghĩa là nó sẵn sàng chấp nhận một kết nối đến khác. Ngoài việc thêm kết nối mới vào danh sách đầu vào để giám sát, phần này đặt ổ cắm máy khách không chặn

    # Handle inputs
    for s in readable:

        if s is server:
            # A "readable" server socket is ready to accept a connection
            connection, client_address = s.accept()
            print >>sys.stderr, 'new connection from', client_address
            connection.setblocking(0)
            inputs.append(connection)

            # Give the connection a queue for data we want to send
            message_queues[connection] = Queue.Queue()

Trường hợp tiếp theo là kết nối được thiết lập với máy khách đã gửi dữ liệu. Dữ liệu được đọc bằng recv(), sau đó được đặt vào hàng đợi để có thể gửi qua ổ cắm và quay lại máy khách

        else:
            data = s.recv(1024)
            if data:
                # A readable client socket has data
                print >>sys.stderr, 'received "%s" from %s' % (data, s.getpeername())
                message_queues[s].put(data)
                # Add output channel for response
                if s not in outputs:
                    outputs.append(s)

Ổ cắm có thể đọc được mà không có sẵn dữ liệu là từ máy khách đã ngắt kết nối và luồng đã sẵn sàng để đóng

            else:
                # Interpret empty result as closed connection
                print >>sys.stderr, 'closing', client_address, 'after reading no data'
                # Stop listening for input on the connection
                if s in outputs:
                    outputs.remove(s)
                inputs.remove(s)
                s.close()

                # Remove message queue
                del message_queues[s]

Có ít trường hợp hơn cho các kết nối có thể ghi. Nếu có dữ liệu trong hàng đợi kết nối, tin nhắn tiếp theo sẽ được gửi. Mặt khác, kết nối sẽ bị xóa khỏi danh sách các kết nối đầu ra để lần tiếp theo thông qua vòng lặp select() không chỉ ra rằng ổ cắm đã sẵn sàng gửi dữ liệu

    # Handle outputs
    for s in writable:
        try:
            next_msg = message_queues[s].get_nowait()
        except Queue.Empty:
            # No messages waiting so stop checking for writability.
            print >>sys.stderr, 'output queue for', s.getpeername(), 'is empty'
            outputs.remove(s)
        else:
            print >>sys.stderr, 'sending "%s" to %s' % (next_msg, s.getpeername())
            s.send(next_msg)

Cuối cùng, nếu có lỗi với ổ cắm, nó sẽ bị đóng

________số 8

Chương trình máy khách mẫu sử dụng hai ổ cắm để minh họa cách máy chủ với select() quản lý nhiều kết nối cùng một lúc. Máy khách bắt đầu bằng cách kết nối từng ổ cắm TCP/IP với máy chủ

import socket
import sys

messages = [ 'This is the message. ',
             'It will be sent ',
             'in parts.',
             ]
server_address = ('localhost', 10000)

# Create a TCP/IP socket
socks = [ socket.socket(socket.AF_INET, socket.SOCK_STREAM),
          socket.socket(socket.AF_INET, socket.SOCK_STREAM),
          ]

# Connect the socket to the port where the server is listening
print >>sys.stderr, 'connecting to %s port %s' % server_address
for s in socks:
    s.connect(server_address)

Sau đó, nó sẽ gửi từng phần của tin nhắn qua từng ổ cắm và đọc tất cả các phản hồi có sẵn sau khi ghi dữ liệu mới

# Sockets from which we expect to read
inputs = [ server ]

# Sockets to which we expect to write
outputs = [ ]
0

Chạy máy chủ trong một cửa sổ và máy khách trong một cửa sổ khác. Đầu ra sẽ trông như thế này, với các số cổng khác nhau

Thăm dò ý kiến ​​​​() trong python là gì?

bỏ phiếu 0. 3. 0 . Một số trường hợp sử dụng có thể bao gồm. - Đợi phản hồi API trả về với mã 200. - Đợi tệp tồn tại (hoặc không tồn tại) - Chờ khóa chuỗi trên tài nguyên hết hạn. a powerful python utility used to wait for a function to return a certain expected condition. Some possible uses cases include: - Wait for API response to return with code 200. - Wait for a file to exist (or not exist) - Wait for a thread lock on a resource to expire.

Chọn () trong python là gì?

select() là một lệnh gọi hệ thống . Nó yêu cầu kernel thông báo khi bất kỳ bộ mô tả nào trong bộ sẵn sàng cho các điều kiện đọc/ghi/ngoại lệ. select() chấp nhận ba lớp mô tả làm tham số mà nó có thể chặn - tập đọc, tập ghi và tập ngoại lệ.

Thăm dò ý kiến ​​hay lựa chọn tốt hơn?

select() chỉ sử dụng (tối đa) ba bit dữ liệu cho mỗi bộ mô tả tệp, trong khi poll() thường sử dụng 64 bit cho mỗi bộ mô tả tệp. Trong mỗi tòa nhà chọc trời gọi cuộc thăm dò () do đó cần sao chép nhiều hơn vào không gian kernel. Một chiến thắng nhỏ cho select() .

Lựa chọn có hoạt động trên Windows không?

Trên Windows, hàm select() cơ bản do thư viện WinSock cung cấp và không xử lý các bộ mô tả tệp không bắt nguồn từ WinSock.