Okay i want to program a server with python.
Therefore i opened a socket and wait for the input.
When i get an input i get an further socket and and address.
Because I want to implement multiple connections at the same time I looked into multi-threading in python.
I create a thread the following way:
t = Thread(target=input, args=(conn, address, ))
t.start()
My input method looks the following:
def input(conn, address): [...]
Now if in this way I get the following stacktrace:
Exception in thread Thread-1:
Traceback (most recent call last): File "/usr/lib/python3.8/threading.py", line 932, in _bootstrap_inner
self.run()
File "/usr/lib/python3.8/threading.py", line 870, in run
self._target(*self._args, **self._kwargs)
TypeError: input expected at most 1 argument, got 2
If i remove the address (and just give the conn) it prints the following:
<socket.socket fd=4, family=AddressFamily.AF_INET, type=SocketKind.SOCK_STREAM, proto=0, laddr=('10.0.0.9', 3306), raddr=('10.0.0.9', 32908)>
How should I understand that?
Solution to the problem:
I need to call the method via self.input not input.
input is a build-in python function which gets one argument so when you are trying to use input inside threading python supposed you want to use the built-in input function. change the function name will fix the issue:
def _input(conn, address): [...]
t = Thread(target=_input, args=(conn, address, ))
t.start()
PS: this way is not a good way to handle multithread networking
Related
As I told in title, I want to create string variables for Threads using input. And delete them using flag.
I need to explain this question step by step.
Let's say, I'm getting input from user. This input by the user will be the name of the Thread variable.
Let the input be equal to love and like. In this case, there will be 2 Threads variable's and Threads created. And their names will be love and like.
To create a Thread, such a code must be given.
The code:
from threading import Thread
import time
import re
# Using while loop. Because I want to create multiple Threads by doing this.
# Dicts
dicts = {}
flags = {}
while True:
# Input
threadName = input('Thread name please? ')
# To delete a Thread
if 'delete' in threadName:
delThread = re.search(r'delete (.*)', threadName)
if delThread:
delThread = list(map(str, delThread.groups()))
delThread = ''.join(delThread)
print('DELETING:', delThread)
flags[delThread] = True
print('DICT NOW:', flags)
else:
# Target function for every Thread. Print a message every 3 secs.
def targetfunc(tname):
while True:
if flags[tname] in flags and flags[tname] == True:
break
print(f"I'm {tname} Thread.")
time.sleep(3)
# Create Threads. 'dicts[threadName]' will be whatever the user enters input.
# Should be string variable.
# 'threadName' is equal to input too.
dicts[threadName] = Thread(target = targetfunc, args = [threadName])
dicts[threadName].start()
flags[threadName] = False
print(dicts)
print(flags)
I'm using 2 dicts. The dicts for creating Threads and the other one for deleting them using flag.
To create, just type what do you want to call to Thread.
To delete, type delete (thread name).
The input from user:
Thread name please? love
{'love': <Thread(Thread-1, stopped 47635696609024)>}
{'love': False}
Thread name please? like
{'love': <Thread(Thread-1, stopped 47635696609024)>, 'like': <Thread(Thread-2, stopped 47635696609024)>}
{'love': False, 'like': False}
Thread name please? delete love
DELETING: love
DICT NOW: {'love': True, 'like': False}
This code throws KeyError for each Thread when I try to delete. Here is the full error.
The error:
Exception in thread Thread-1:
Traceback (most recent call last):
File "/usr/lib/python3.7/threading.py", line 917, in _bootstrap_inner
self.run()
File "/usr/lib/python3.7/threading.py", line 865, in run
self._target(*self._args, **self._kwargs)
File "./prog.py", line 27, in targetfunc
KeyError: 'love'
Exception in thread Thread-2:
Traceback (most recent call last):
File "/usr/lib/python3.7/threading.py", line 917, in _bootstrap_inner
self.run()
File "/usr/lib/python3.7/threading.py", line 865, in run
self._target(*self._args, **self._kwargs)
File "./prog.py", line 27, in targetfunc
KeyError: 'like'
That's the program. How to fix this problem?
What I want to achieve is:
When I type a name, that name must create a new Thread with that name. But when I type delete (thread name) this should stop (thread name) Thread.
I hope I could explain it well. Hope you help.
The problem is you are checking the dictionary entry instead of checking if that key exists.
Change this line:
if flags[tname] in flags and flags[tname] == True:
To this:
if tname in flags and flags[tname] == True:
With this change, the code runs correctly.
I am trying to make a simple simulation of communication between two devices via serial ports(on linux to be clear). I have came up with idea to put reading from serial port into diffrent thread, but the problem is that this thread throw me an error like this:
Is open? True
Exception in thread Thread-1:
Traceback (most recent call last):
File "/usr/lib/python3.7/threading.py", line 926, in _bootstrap_inner
self.run()
File "/usr/lib/python3.7/threading.py", line 870, in run
self._target(*self._args, **self._kwargs)
File "client.py", line 18, in func
if len(ser.readline()) > 0:
File "/home/bartosz/PycharmProjects/socket-serial-comm/venv/lib/python3.7/site-packages/serial/serialposix.py", line 478, in read
raise portNotOpenError
serial.serialutil.SerialException: Attempting to use a port that is not open
So it seems that port I am trying to use is not open, but when I am printing from this thread print("Is open? ", ser.is_open)
it gives me True, and I can't open the port in thread because of that.
Here's my code:
import serial
import threading
import time
ser = serial.Serial('/dev/pts/0', timeout=1)
def func():
print("Is open? ", ser.is_open)
while True:
if len(ser.readline()) > 0:
print(ser.readline())
x = threading.Thread(target=func, args=ser)
x.start()
time.sleep(1)
ser.write(b'some text\n')
time.sleep(1)
ser.close()
Any thoughts why this behave like that?
This is working exactly as you coded it.
The process that is reading the serial port is running forever in an infinite loop with While True:, but the port itself is ser.close() about 2 seconds after the processing thread is started.
Since ser.readline() is executed even after ser.close(), the question error occurs.
Before calling ser.close(), you need to install a mechanism to terminate def func(): thread processing.
By the way, the process of judging with len(ser.readline()) in if statement and then print(ser.readline()), there is data requires input of two lines, but the first line is not displayed, it would be weird to just print the next line.
You should review the process.
I'm trying to connect to host by different threads in python but getting error sometimes(1 times in 25 times execution)
I have seen similar threads and hoped to update pip to 8.1.1 will solve this but did not solve though.
code snippet:
def getkpis(self,cmd,host):
ssh=paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
try:
ssh.connect(host,username='root',look_for_keys=True)
stdin, stdout, stderr = ssh.exec_command(cmd)
paramiko.util.log_to_file("kpiparamiko.log")
output=stdout.read()
appendarray=output.split('\n')
sys.stdin.flush()
ssh.close()
except paramiko.SSHException, e:
print str(e)
Error seen:
Exception in thread Thread-1:
Traceback (most recent call last):
File "/usr/lib64/python2.7/threading.py", line 811, in __bootstrap_inner
self.run()
File "/usr/lib64/python2.7/threading.py", line 764, in run
self.__target(*self.__args, **self.__kwargs)
File "/conf/home/smodugu/kpiparse.py", line 56, in getkpis
ssh.connect(host,username='root',look_for_keys=True)
File "/usr/lib/python2.7/site-packages/paramiko/client.py", line 338, in connect
t.start_client()
File "/usr/lib/python2.7/site-packages/paramiko/transport.py", line 493, in start_client
raise e
RequirementParseError: Invalid requirement, parse error at "''"
Yesterday, I was able to get around this by using an older version of setuptools, pip install "setuptools<34" but then today the problem came back. I was able to get around it by adding a 0.1 second sleep in the loop that was queuing the threads. Why multiple threaded calls to paramiko's SSHClient cause this error with pip/setuptools, I have no idea.
It looks like the connect function is not thread safe in the version of paramiko for python2.7
The solution is to use the Lock object from the threading module,
from threading import Lock.
Then wrap the call to the connect function of the paramiko client with the lock object.
For example:
from threading import Lock
lock = Lock()
...
lock.acquire()
client.connect(...)
lock.release()
The code above makes so that only one thread will use the connect at a time, which solves the problem that the function is not thread safe.
*** I am not sure if the problem exists in newer versions of paramiko, worth a look.
I want to make a program which is checks the given url for every 10 seconds
def listener(url):
print ("Status: Listening")
response = urllib.request.urlopen(url)
data = response.read()
text = data.decode('utf-8')
if text == 'Hello World. Testing!':
print("--Action Started!--")
t = Timer(10.0,listener('http://test.com/test.txt'))
t.start()
here is the output:
Status: Listening
Exception in thread Thread-1:
Traceback (most recent call last):
File "/usr/lib/python3.4/threading.py", line 920, in _bootstrap_inner
self.run()
File "/usr/lib/python3.4/threading.py", line 1186, in run
self.function(*self.args, **self.kwargs)
TypeError: 'NoneType' object is not callable
It runs the function for one time, after 10 seconds the error appears
Currently, the result of your listener function call is being given to Timer, which is resultantly None, as you need to make an explicit return so your Timer has something to operate on.
You have to place the argument for your listener() in another parameter, like this. Note that args must be a sequence, thus the tuple with the comma placed after your url. Without this tuple, you are passing each individual character from 'http://test.com/test.txt' as an argument to listener.
t = Timer(10.0,listener,args=('http://test.com/test.txt',))
As you can see in documentation here, arguments must be passed as a third parameter.
I am new to Python and trying a multiprocessing.pool program to process files, it works fine as long as there are no exceptions. If any of the thread/process gets an exception the whole program waits for the thread
snippet of the code:
cp = ConfigParser.ConfigParser()
cp.read(gdbini)
for table in cp.sections():
jobs.append(table)
#print jobs
poolreturn = pool.map(worker, jobs)
pool.close()
pool.join()
Failure Message:
Traceback (most recent call last):
File "/opt/cnet-python/default-2.6/lib/python2.6/threading.py", line 525, in __bootstrap_inner
self.run()
File "/opt/cnet-python/default-2.6/lib/python2.6/threading.py", line 477, in run
self.__target(*self.__args, **self.__kwargs)
File "/opt/cnet-python/default-2.6/lib/python2.6/multiprocessing/pool.py", line 259, in _handle_results
task = get()
TypeError: ('__init__() takes exactly 3 arguments (2 given)', <class 'ConfigParser.NoOptionError'>, ("No option 'inputfilename' in section: 'section-1'",))
I went ahead added a exception handler to terminate the process
try:
ifile=cp.get(table,'inputfilename')
except ConfigParser.NoSectionError,ConfigParser.NoOptionError:
usage("One of Parameter not found for"+ table)
terminate()
but still it waits, not sure whats missing.
In Python 3.2+ this works as expected. For Python 2, this bug was fixed in r74545 and will be available in Python 2.7.3. In the mean time, you can use the configparser library which is a backport of the configparser from 3.2+. Check it out.
I had the same issue. It happens when a worker process raises a user exception which has a custom constructor. Make sure your exception (ConfigParser.NoOptionError in that case) initializes the base exception with exactly two arguments:
class NoOptionError(ValueError):
def __init__(self, message, *args):
super(NoOptionError, self).__init__(message, args)