# 04 message queue ZMQ publisher subscriber calculation π simple program.

2020-12-08 14:14:53

`#  Little knowledge ： Calculation π One of the ways to do it is , Randomly to a side length of n A square of beans .#  And see if the beans are using n Is a quarter of the radius of the circle , Square area ：n*n, The area of a quarter circle ：π*n*n/4#  So the probability of falling within the quarter circle is π/4, So we can figure out π Value .#  Our program is to talk about zmq Release - The flow of the subscription process ,#  By calculation π Value as an example to calculate .#  First publisher bitsource Randomly generate a string , Even bits of the string are ordinates , Odd bits are abscissa .#  A string represents a point , Convert odd digits to abscissa , Convert even digits to ordinates , And then by calculating #  The distance from this point to the origin , To determine whether the radius is B Inside the circle , Through a lot of simulation , To calculate π.import random, threading, time, zmqB = 32  # number of bits of precision in each random integerdef ones_and_zeros(digits):    """Express `n` in at least `d` binary digits, with no special prefix."""    # getrandbits()    #  Method returns the specified size （ In bits ） The integer of .    return bin(random.getrandbits(digits)).lstrip('0b').zfill(digits)#  Publisher def bitsource(zcontext, url):    #  Publish subscribe function , Publisher .    """Produce random points in the unit square."""    #  Create an object . Publisher object     zsock = zcontext.socket(zmq.PUB)    #  binding URL    zsock.bind(url)    while True:        #  It's been sent all the time. This is 32 Bit binary character .        #  Here a string represents a dot .        zsock.send_string(ones_and_zeros(B * 2))        #  pause 0.01 second .        time.sleep(0.01)#  subscriber 1def always_yes(zcontext, in_url, out_url):    """Coordinates in the lower-left quadrant are inside the unit circle."""    #  Create a subscriber object .    isock = zcontext.socket(zmq.SUB)    #  Connecting to the publisher URL    isock.connect(in_url)    #  Set filter conditions , receive 00 At the beginning     #  If it starts with 00 Words , So this point x、y No value is more than half the radius     #  It must be within a quarter circle .    isock.setsockopt(zmq.SUBSCRIBE, b'00')    #  push .    osock = zcontext.socket(zmq.PUSH)    #  Connect to receive push URL    osock.connect(out_url)    while True:        #  Receiving messages from subscribers .        isock.recv_string()        #  Push to the publisher . So we send it directly here Y        osock.send_string('Y')#  subscriber 2def judge(zcontext, in_url, pythagoras_url, out_url):    """Determine whether each input coordinate is inside the unit circle."""    #     #  Create a subscriber object .    isock = zcontext.socket(zmq.SUB)    #  Connect URL    isock.connect(in_url)    #  Set the filter conditions for receiving subscriptions .    for prefix in b'01', b'10', b'11':        isock.setsockopt(zmq.SUBSCRIBE, prefix)    #  Set up a response object .    psock = zcontext.socket(zmq.REQ)    psock.connect(pythagoras_url)    #  Set up a push object .    osock = zcontext.socket(zmq.PUSH)    osock.connect(out_url)    #  Here's the Pythagorean theorem , It's two points on the axis , Sum of squares .    unit = 2 ** (B * 2)    #  Here we need to calculate whether it is within the quarter circle .    while True:        #  Receiving messages from publishers .        bits = isock.recv_string()        #  Extracting this point x coordinate ,y coordinate .        n, m = int(bits[::2], 2), int(bits[1::2], 2)        #  Send to the client requester         psock.send_json((n, m))        #  Then it receives the data sent by the client's requester for processing .        sumsquares = psock.recv_json()        #  Judge whether it is in the circle .        osock.send_string('Y' if sumsquares < unit else 'N')#  Request side ,def pythagoras(zcontext, url):    """Return the sum-of-squares of number sequences."""    zsock = zcontext.socket(zmq.REP)    zsock.bind(url)    while True:        #  Here's the data request , Then the requested data is processed and sent out .        numbers = zsock.recv_json()        zsock.send_json(sum(n * n for n in numbers))#  Summary , Calculate π Value .def tally(zcontext, url):    """Tally how many points fall within the unit circle, and print pi."""    zsock = zcontext.socket(zmq.PULL)    zsock.bind(url)    #  Here's how to receive a Y p+4, Received a N ,q + 1    #  And then calculate the ratio , This is what we worked out π Value .    p = q = 0    while True:        decision = zsock.recv_string()        q += 1        if decision == 'Y':            p += 4        print(decision, p / q)#  We use multithreading , Each function above starts a thread ,.def start_thread(function, *args):    thread = threading.Thread(target=function, args=args)    thread.daemon = True  # so you can easily Ctrl-C the whole program    thread.start()def main(zcontext):    pubsub = 'tcp://127.0.0.1:6700'    reqrep = 'tcp://127.0.0.1:6701'    pushpull = 'tcp://127.0.0.1:6702'    start_thread(bitsource, zcontext, pubsub)    start_thread(always_yes, zcontext, pubsub, pushpull)    start_thread(judge, zcontext, pubsub, reqrep, pushpull)    start_thread(pythagoras, zcontext, reqrep)    start_thread(tally, zcontext, pushpull)    #  This is the main thread , End of main thread , The other threads will end .    time.sleep(30)if __name__ == '__main__':    main(zmq.Context())`

https://chowdera.com/2020/12/20201208141419895w.html