Warm tip: This article is reproduced from stackoverflow.com, please click
python-3.x client-server

What are the value states of read/write in selectors.EVENT_READ | selectors.EVENT_WRITE?

发布于 2020-03-27 10:24:58

In the question Python - non-blocking sockets using selectors the following code is used:

events = selectors.EVENT_READ | selectors.EVENT_WRITE

The values of event_read or event_write flags are not mentioned nor explained at https://docs.python.org/3/library/selectors.html. Neither is an explanation give in the select() module or given at https://realpython.com/python-sockets/. It would be appreciated to emphasize on this particular part or provide reading material that explains this in much more detail than provided by python docs or the realpython link.

In relation, during service connection this is used: if mask & selectors.EVENT_READ:

I can imaging that the evaluation can be 1 & 1 or 2 & 2 and in both cases the code within the if-statement is executed. So if the expression evaluates 3 & 1 it would not execute, right?

The code:

def service_connection(key, mask):
    sock = key.fileobj
    data = key.data
    if mask & selectors.EVENT_READ:
        recv_data = sock.recv(1024)
        if recv_data:
            data.outb += recv_data
        else:
            print('closing connection to', data.addr)
            sel.unregister(sock)
            sock.close()
    if mask & selectors.EVENT_WRITE:
        if data.outb:
            print('echoing', repr(data.outb), 'to', data.addr)
            sent = sock.send(data.outb)
            data.outb = data.outb[sent:]
Questioner
ZF007
Viewed
72
ZF007 2019-07-04 21:37

In the python selectors.py file the following variables are created:

  1. EVENT_READ = (1 << 0)
  2. EVENT_WRITE = (1 << 1)

If both are printed the following values are given for each state:

print(EVENT_READ)  = 1

print(EVENT_WRITE) = 2

What happes is the following (a bitwise shift to the left):

bin(0b1) -> '0b1' # bitwise operator for EVENT_READ = (1 << 0)

bin(0b1) -> '0b10' # bitwise operator for EVENT_WRITE = (1 << 1)

In the case of if mask & selectors.EVENT_READ: a "bitwise and" is applied. Each bit of the output is 1 if the corresponding bit of mask AND of selectors.EVENT_READ is 1, otherwise it's 0.

mask = integer # 0, 1, 2, 3 or higher.

if mask & EVENT_READ:
    print ('mask & EVENT_READ')

if mask & EVENT_WRITE:
    print ('mask & EVENT_WRITE')
  1. if mask = 0 | None of the above if-statements is turefor below.
  2. if mask = 1 | Only the event_read is true.
  3. if mask = 2 | Only the event_write is true.
  4. if mask = 3 | Both if statements are true.

The if-statement validation value output and order for each mask value repeats itself for mask = 5, 6, etc..

Bitwise operators references 1 and 2.