i don't understand why thread lock is used when there is only one thread. here is the code i've seen online isn't thread lock used only when there's more than 2 threads excluding main thread?
import socket
import threading
tLock = threading.Lock()
shutdown = False
def receving(name, sock):
while not shutdown:
try:
tLock.acquire()
while True:
data, addr = sock.recvfrom(1024)
print str(data)
except:
pass
finally:
tLock.release()
host = '127.0.0.1'
port = 0
server = ('127.0.0.1',5000)
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.bind((host, port))
s.setblocking(0)
rT = threading.Thread(target=receving, args=("RecvThread",s))
rT.start()
alias = raw_input("Name: ")
message = raw_input(alias + "-> ")
while message != 'q':
if message != '':
s.sendto(alias + ": " + message, server)
tLock.acquire()
message = raw_input(alias + "-> ")
tLock.release()
time.sleep(0.2)
shudown = True
rT.join()
s.close()
also i do not understand why thread lock was used in this line
tLock.acquire()
message = raw_input(alias + "-> ")
tLock.release()
what's going to happen if the thread lock was not used?
The design of your program may be based on a flawed understanding of what locks are. If you expect that thread B will wake up from waiting to acquire a lock when thread A releases it, then you may be making a mistake. That's not quite how it works.
There are different ways that locking can work, but unless the documentation for the library that you are using promises more than the bare minimum (and, the doc for Python's Threading module does not make that promise), then the bare minimum is all you should only assume;
If thread A calls lck.acquire(), when lck is available, then the call will immediately succeed.
If thread A calls lck.release() while one or more other threads is blocked in an lck.acquire() call, then some time later, at least one of those threads will be allowed to re-try acquiring lck.
lck.acquire() call will return,Here's a simplified version of your receive thread:
def receiving(name, sock):
while not shutdown:
tLock.acquire();
data = sock.recvfrom(...);
doSomethingWith(data);
tLock.release();
Let's say, that the main thread is waiting in tLock.acquire() when a message arrives on sock. Here's what most likely happens:
receive thread
-------------------
receive the message
doSomethingWith(data)
tLock.release()
- set status of tLock to "available"
- Sees main thread is waiting for tLock
- Changes state of main thread to RUNNABLE
- returns.
tLock.acquire()
- Sees that tLock is "available",
- Changes it to "locked" and returns.
sock.recvfrom(...)
- no message is immediately available,
- goes into a wait state.
system heartbeat interrupt handler
----------------------------------
triggered by hardware
Sees that main thread is RUNNABLE
Kicks some other RUNNING thread off its CPU, and
allows the main thread to start running on that CPU.
main thread
-----------
...still in a call to tLock.acquire()
- sees that tLock still is "locked",
- goes back to waiting.
That process can repeat itself many times without the tLock.acquire() call ever returning in the main thread.
This problem is an example of resource starvation.
The lines here:
tLock.acquire()
message = raw_input(alias + "-> ")
effectively wait for a reply message from the server before prompting for the user to send a query/request up to the server
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With