paolojo
Posts: 117
Joined: Mon Oct 26, 2015 3:32 pm

Multiprocessing on Raspberry

Fri Nov 20, 2015 1:02 pm

Hi to all!
I developed an application that reads a input status (GPIO nr.4) using the following command:

Code: Select all

GPIO.add_event_detect(4,
                              GPIO.RISING,
                              callback=self.my_callback,
                              bouncetime=500
                                          )
where my_callback is

Code: Select all

def my_callback(self, channel):  
        print "rising detected on GPIO 4"
        self.n += 1     
Now I would move another step: In "my_callback" I would open a new process that executes another script called "my_script.py". In addition I would control the execution time of this new process: if the execution time of "my_script.py" is greater than a timeout value, I would kill the process. Can you help me? I'm trying to reading some documentations(https://docs.python.org/3/library/multiprocessing.html) but I don't understand how can I proceed.
Thank you to all
Paolo

User avatar
elParaguayo
Posts: 1943
Joined: Wed May 16, 2012 12:46 pm
Location: London, UK

Re: Multiprocessing on Raspberry

Fri Nov 20, 2015 3:15 pm

I haven't forgotten about this! I may have some more time tomorrow to take a proper look but you may well get some better answers before then.
RPi Information Screen: plugin based system for displaying weather, travel information, football scores etc.

paolojo
Posts: 117
Joined: Mon Oct 26, 2015 3:32 pm

Re: Multiprocessing on Raspberry

Fri Nov 20, 2015 4:59 pm

Hi elParaguayo!!
I've changed the forum argument because I thought that "multiprocessing" was not related to the GUI question!
So, I'm happy to wait for your reply! ;)

User avatar
elParaguayo
Posts: 1943
Joined: Wed May 16, 2012 12:46 pm
Location: London, UK

Re: Multiprocessing on Raspberry

Sat Nov 21, 2015 7:07 am

If it were me, I'd do something like this:

Code: Select all

from threading import Thread
from subprocess import Popen
import shlex
from time import sleep

class TimeoutProcess(Thread):
    """New class that calls a subprocess but terminates it if the process has
       not completed within the necessary time period.

       Takes two parameters:
         process: (string) command to be run
         timeout: (int) number of seconds until process is killed
    """
    def __init__(self, process, timeout):
        Thread.__init__(self)

        # We use shlex.split to turn the command into something that the
        # subprocess module likes to use
        self.process = shlex.split(process)

        # Make sure the timeout is an integer
        self.timeout = int(timeout)

    def run(self):

        # Create an object that runs the process
        self.proc = Popen(self.process)

        # Set a flag to show the process is running
        running = True

        # We'll check the status of the process every second
        for _ in range(self.timeout):

            # poll will return None if the process hasn't exited (and the
            # exit code once it has)
            if self.proc.poll() is not None:
                # process has exited so change flag
                running = False
                
                # No need to keep looping so let's exit
                break

            # If we're here, process is still running so sleep for 1 second
            sleep(1)

        # The loop's exited so we've either reached the timeout period
        # or the process has already finished.
        # Have a look at the flag to see which is true
        if running:

            # Process is still running so let's kill it
            self.proc.terminate()

            #print "Process killed"

# To use it we create an instance
t = TimeoutProcess("/path/to/my/command", 5)

# and run it
t.start()

# NB This thread is not daemonised i.e. your main script won't exit until this
# thread finishes (e.g. process completes or it's killed after the timeout)
# If that's not the behaviour you want, call t.daemon = True before starting
# the thread.
I hope this helps.
RPi Information Screen: plugin based system for displaying weather, travel information, football scores etc.

paolojo
Posts: 117
Joined: Mon Oct 26, 2015 3:32 pm

Re: Multiprocessing on Raspberry

Wed Nov 25, 2015 10:44 pm

Hi my friend!
I've just tried your code.
So, my situation is this:
- the script that contains your above code is called "main_script.py",
- the process is called "stamp.py" and in detail is the following:

Code: Select all

#!/usr/bin/python
def pr(n):
        print "n = ", n
Therefore, when I run "main_script.py", I obtain the following error:

Code: Select all

Traceback (most recent call last):
   File "main_script.py", line 153, in my_callback
     t = TimeoutProcess(stamp.pr, 5)
   File "main_script.py", line 54, in __init__
     self.process = shlex.split(process)
   File "/usr/lib/python2.7/shlex.py", line 279, in split
     return list(lex)
   File "/usr/lib/python2.7/shlex.py", line 269, in next
     token = self.get_token()
   File "/usr/lib/python2.7/shlex.py", line 96, in get_token
     raw = self.read_token()
   File "/usr/lib/python2.7/shlex.py", line 124, in read_token
     nextchar = self.instream.read(1)
 AttributeError: 'function' object has no attribute 'read'
Have you an idea about what is happening?
Goodnight
Paolo

User avatar
elParaguayo
Posts: 1943
Joined: Wed May 16, 2012 12:46 pm
Location: London, UK

Re: Multiprocessing on Raspberry

Thu Nov 26, 2015 12:13 am

It looks like you're trying to pass a function to the TimeoutProcess. That wasn't how I'd set it up. I thought you had a separate python script that you wanted to run, so you pass the command to run that script instead e.g.

Code: Select all

t = TimeoutProcess("python stamp.py", 5)
Are you actually importing stamp into your script instead?
RPi Information Screen: plugin based system for displaying weather, travel information, football scores etc.

paolojo
Posts: 117
Joined: Mon Oct 26, 2015 3:32 pm

Re: Multiprocessing on Raspberry

Thu Nov 26, 2015 2:28 pm

Hi!
I call the process by the following code row:

Code: Select all

t=Timeoutprocess(stamp.pr(self.n),5)
Where:
- "stamp.py" is script
- "pr" is a function of "stamp.py"
-"self.n" is a parameter passed to the function "pr"

Is it correct?

User avatar
elParaguayo
Posts: 1943
Joined: Wed May 16, 2012 12:46 pm
Location: London, UK

Re: Multiprocessing on Raspberry

Thu Nov 26, 2015 3:09 pm

No.

The main question I have is whether "stamp.py" is run separately or whether you're importing it into your main script (i.e. have you got an "import stamp" line somewhere?)

The code I wrote for you won't work where you are calling python functions that are available after importing the function. It works where you would run a command separately (e.g. "python stamp.py").

It's going to be much easier if you post your main and stamp scripts and explain how you want them to interact.

If you've imported the function then I might be tempted to use something like the multiprocessing module to run a process in the background and then kill it if necessary.
RPi Information Screen: plugin based system for displaying weather, travel information, football scores etc.

paolojo
Posts: 117
Joined: Mon Oct 26, 2015 3:32 pm

Re: Multiprocessing on Raspberry

Thu Nov 26, 2015 9:03 pm

elParaguayo wrote:No.
The main question I have is whether "stamp.py" is run separately or whether you're importing it into your main script (i.e. have you got an "import stamp" line somewhere?)
"stamp.py" is run separately, I have an "import stamp" line in the main script.
The code I wrote for you won't work where you are calling python functions that are available after importing the function. It works where you would run a command separately (e.g. "python stamp.py").
If you've imported the function then I might be tempted to use something like the multiprocessing module to run a process in the background and then kill it if necessary.
Ok, but what is the difference between the code that you wrote and the multiprocessing module that you are suggesting me?
Could you show me how to proceed with the multiprocessing module?

The main code is the code that you wrote for me on "Tue Nov 10, 2015 6:52": here follows the code with:
-> the "stamp.py" import line
--> the exact place where I would call the process "stamp.py"

Code: Select all

# MainApp.py
from random import randint
from glob import glob
from os.path import join, dirname

from kivy.app import App
from kivy.clock import Clock
from kivy.core.window import Window
from kivy.properties import StringProperty
from kivy.uix.carousel import Carousel
from kivy.uix.image import AsyncImage
from kivy.uix.scatter import Scatter
from kivy.uix.floatlayout import FloatLayout
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.label import Label
from kivy.uix.image import Image
import RPi.GPIO as GPIO  

# ************************* HERE I IMPORT THE SCRIPT STAMP.PY ***************************************
import stamp.py


class Screen(FloatLayout):
    def __init__(self, **kwargs):
        super(Screen, self).__init__(**kwargs)

        # Here's your GPIO stuff
        GPIO.setmode(GPIO.BCM) 
        GPIO.setup(4, GPIO.IN, pull_up_down=GPIO.PUD_DOWN) 
        self.n = 0

        # Add a call function
        GPIO.add_event_detect(4,
                              GPIO.RISING,
                              callback=self.my_callback,
                              bouncetime=500) 
    
        layout = BoxLayout(orientation='horizontal', spacing=3)
        #il parametro spacing determina la distanza tra i due box

        # Create a template for your text
        self.tx ='[b][size=45][color=ff3333]The value of n is {n}[/color][/size][/b]'

        self.lbl = Label(text=self.tx.format(n=self.n), 
                         markup=True, 
                         size_hint=(.4, 1),
                         pos_hint={"center_x":.5, "center_y":.7})
   
        carousel = Carousel(direction='right', size_hint=(.6, 1))

        carousel.loop = True

        curdir = dirname(__file__)

        for filename in glob(join(curdir, '/home/pi/mufolder/img', '*')):
            picture = Image(source=filename,allow_stretch=True)
            carousel.add_widget(picture)

        Clock.schedule_interval(carousel.load_next, 5)

        layout.add_widget(carousel)
        layout.add_widget(self.lbl)
        
        self.add_widget(layout)

    def my_callback(self, channel):  
        print "rising detected on GPIO 4"
        self.n += 1

        # Update our template with the current value of n
        tx = self.tx.format(n=self.n)

        # Print it
        print tx

        # Update the text on the label.
        self.lbl.text = tx

        # *************** HERE I WANT CALL THE NEW PROCESS STAMP.PR PASSING THE VALUE "self.n" *********
         


class MainApp(App):
    def build(self):
        #imposto il colore dello sfondo
        Window.clearcolor = (255, 255, 255, 1)
        #Window.size=(500, 500)
        return Screen()

MainApp().run()
and the "stamp.py" code is the following:

Code: Select all

# STAMP.PY

#!/usr/bin/python
def pr(n):
        print "n = ", n
Obviously, "stamp.py" is only an example that help me in this phase how multiprocessing module works

Thanks a lot elParaguayo!!
Paolo

User avatar
elParaguayo
Posts: 1943
Joined: Wed May 16, 2012 12:46 pm
Location: London, UK

Re: Multiprocessing on Raspberry

Thu Nov 26, 2015 10:30 pm

paolojo wrote:"stamp.py" is run separately, I have an "import stamp" line in the main script.
That's not running separately. It is only run when you call "stamp.pr(n)" from your main script. There's nothing wrong with that at all and I'm sure we can still get it to work.

However, rather than giving an example of stamp.py can you say what it's actually going to do i.e. is it a function that you're going to import? do you need to pass parameters to it? do you need to get values back from it?

My code used the subprocess module (which can be used to call shell commands) to run a process in the background. However, subprocess can't be used to run a python function.

If you're just looking to run a python function in the background, this could be done in a thread however there's no neat way of killing a thread to my knowledge (there are also numerous conversations on StackOverflow about why killing threads is bad).

The multiprocessing module is like threading, but it runs the function in a separate process which does allow it to be killed (it's probably got lots of other benefits which I'm failing to mention too).

Which solution you use depends on what your code is and what you want it to do.
RPi Information Screen: plugin based system for displaying weather, travel information, football scores etc.

paolojo
Posts: 117
Joined: Mon Oct 26, 2015 3:32 pm

Re: Multiprocessing on Raspberry

Fri Nov 27, 2015 3:08 pm

That's not running separately. It is only run when you call "stamp.pr(n)" from your main script. There's nothing wrong with that at all and I'm sure we can still get it to work.
Ok, that's what I want: "stamp.pr(n)" must run when I call it from my main script (see the above post)
However, rather than giving an example of stamp.py can you say what it's actually going to do i.e. is it a function that you're going to import? do you need to pass parameters to it? do you need to get values back from it?
"stamp.py" is an imported python script that contains a function called "pr".
The main script, when calls the function "pr", passes "self.n" as parameter to "pr" function.
In addition, the function "pr" returns to main script a flag that is 0 when the "pr" has finished, and 1 when the function is still operating
If you're just looking to run a python function in the background, this could be done in a thread however there's no neat way of killing a thread to my knowledge (there are also numerous conversations on StackOverflow about why killing threads is bad).
The multiprocessing module is like threading, but it runs the function in a separate process which does allow it to be killed (it's probably got lots of other benefits which I'm failing to mention too).
Which solution you use depends on what your code is and what you want it to do.
So, I think that the best way is run the function in a separate process. Do you agree with me?

User avatar
elParaguayo
Posts: 1943
Joined: Wed May 16, 2012 12:46 pm
Location: London, UK

Re: Multiprocessing on Raspberry

Mon Nov 30, 2015 10:33 pm

Can you post your actual stamp.py code?

The example you've given doesn't make sense to run in a process because it returns a value immdiately.
RPi Information Screen: plugin based system for displaying weather, travel information, football scores etc.

paolojo
Posts: 117
Joined: Mon Oct 26, 2015 3:32 pm

Re: Multiprocessing on Raspberry

Tue Dec 01, 2015 3:29 pm

In this days I've found an interesting code that permit me to send a parameters values to a web database (see https://parse.com/docs/rest/guide/)
So, now I want substitute the stamp.py with a code similar to the following (I must still do some adjustments):

Code: Select all


#PARSE.PY (that substitutes the stamp.py)
import json,httplib
connection = httplib.HTTPSConnection('api.parse.com', 443)
connection.connect()
connection.request('PUT', '/1/classes/GameScore/Ed1nuqPvcm', json.dumps({
       "score": 73453
     }), {
       "X-Parse-Application-Id": "${APPLICATION_ID}",
       "X-Parse-REST-API-Key": "${REST_API_KEY}",
       "Content-Type": "application/json"
     })
result = json.loads(connection.getresponse().read())
print result 
How you can imagine this script doesn't return a value immdiately.

User avatar
elParaguayo
Posts: 1943
Joined: Wed May 16, 2012 12:46 pm
Location: London, UK

Re: Multiprocessing on Raspberry

Tue Dec 01, 2015 7:17 pm

I'm still not sure I see why you need to kill the process after a certain amount of time.

Is it a case that the web request may not work and you have a timeout (i.e. processing and returning the response is trivial once you've received it)?

If that's the issue then you should be able to handle that by catching the timeout error rather than forcibly killing the process.

All this could be put in a thread so it runs in the background. The return value could be put in a queue with your main script reading that.
RPi Information Screen: plugin based system for displaying weather, travel information, football scores etc.

paolojo
Posts: 117
Joined: Mon Oct 26, 2015 3:32 pm

Re: Multiprocessing on Raspberry

Wed Dec 02, 2015 10:48 am

Ok, I agree with you when you say that there isn't the need to kill the web request process.
We can proceed in the following manner:
- we can put the web request in a thread that runs in background;
- if within a time interval (timeout) the "web request thread" doesn't return a valid response, the thread passes an error flag to the main script.
- when the main script receives the "error flag" from "web request thread", the main script calls another time the "web request thread"

The most important aspect is that, in case of connection problems, the "web request thread" should not block or slow down the main script.

What do you think about? Do you agree with me?

User avatar
elParaguayo
Posts: 1943
Joined: Wed May 16, 2012 12:46 pm
Location: London, UK

Re: Multiprocessing on Raspberry

Wed Dec 02, 2015 12:51 pm

Yes!

Will try to take a look tonight if I can.
RPi Information Screen: plugin based system for displaying weather, travel information, football scores etc.

paolojo
Posts: 117
Joined: Mon Oct 26, 2015 3:32 pm

Re: Multiprocessing on Raspberry

Wed Dec 02, 2015 1:20 pm

GREAT! ;)

User avatar
elParaguayo
Posts: 1943
Joined: Wed May 16, 2012 12:46 pm
Location: London, UK

Re: Multiprocessing on Raspberry

Thu Dec 03, 2015 12:20 am

Bit busy with work at the moment so I've not finished yet.

I have written some code that will do the web request in a separate thread and return data to the main thread. If the request times out (or if there is another error) the thread also returns this.

I just want to do the last bit to link it to the kivy script and I'll post it when it's done.
RPi Information Screen: plugin based system for displaying weather, travel information, football scores etc.

paolojo
Posts: 117
Joined: Mon Oct 26, 2015 3:32 pm

Re: Multiprocessing on Raspberry

Thu Dec 03, 2015 6:17 am

No problems my dear!thanks a lot!

User avatar
elParaguayo
Posts: 1943
Joined: Wed May 16, 2012 12:46 pm
Location: London, UK

Re: Multiprocessing on Raspberry

Thu Dec 03, 2015 11:21 pm

OK, probably overkill for your needs...

main.py

Code: Select all

#!/usr/bin/env python
from random import randint
from glob import glob
from os.path import join, dirname

from kivy.app import App
from kivy.clock import Clock
from kivy.core.window import Window
from kivy.properties import StringProperty
from kivy.uix.carousel import Carousel
from kivy.uix.image import AsyncImage
from kivy.uix.scatter import Scatter
from kivy.uix.floatlayout import FloatLayout
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.label import Label
from kivy.uix.image import Image
from kivy.uix.button import Button
import RPi.GPIO as GPIO

from webtimeout import WebTimeout

# Some of your web stuff is constant so define it here:

headers = {"X-Parse-Application-Id": "${APPLICATION_ID}",
           "X-Parse-REST-API-Key": "${REST_API_KEY}",
           "Content-Type": "application/json"
           }

address = "https://api.parse.com//1/classes/GameScore/Ed1nuqPvcm"

method = "PUT"

data = None

class Screen(FloatLayout):
    def __init__(self, **kwargs):
        super(Screen, self).__init__(**kwargs)

        # # Here's your GPIO stuff
        GPIO.setmode(GPIO.BCM)
        GPIO.setup(4, GPIO.IN, pull_up_down=GPIO.PUD_DOWN)
        self.n = 0

        # Add a call function
        GPIO.add_event_detect(4,
                              GPIO.RISING,
                              callback=self.my_callback,
                              bouncetime=500)


        layout = BoxLayout(orientation='horizontal', spacing=3)
        #il parametro spacing determina la distanza tra i due box

        # Create a template for your text
        self.tx ='[b][size=45][color=ff3333]The value of n is {n}[/color][/size][/b]'

        self.lbl = Label(text=self.tx.format(n=self.n),
                         markup=True,
                         size_hint=(.4, 1),
                         pos_hint={"center_x":.5, "center_y":.7})

        # This is a blank label for handling the response from the web request
        self.callback_lbl = Label(text="", size_hint=(None,None),
                                  size=(200,50), pos=(200,100))

        carousel = Carousel(direction='right', size_hint=(.6, 1))

        carousel.loop = True

        curdir = dirname(__file__)

        for filename in glob(join(curdir, '/home/pi/mufolder/img', '*')):
            picture = Image(source=filename,allow_stretch=True)
            carousel.add_widget(picture)

        Clock.schedule_interval(carousel.load_next, 5)

        layout.add_widget(carousel)
        layout.add_widget(self.lbl)

        self.add_widget(layout)
        self.add_widget(self.callback_lbl)

    def my_callback(self, channel):
        print "rising detected on GPIO 4"
        self.n += 1

        # Update our template with the current value of n
        tx = self.tx.format(n=self.n)

        # Print it
        print tx

        # Update the text on the label.
        self.lbl.text = tx


        # This is where the web request is created
        # if you need to submit data, prepare that here (assuming it's not
        # constant) e.g.
        data = {"score": self.n}

        # The example below is set up to run a callback method when the web
        # requests ends
        wt = WebTimeout(address=address, headers=headers, timeout=10,
                        method=method, data=data,
                        callback=self.my_web_callback)

        wt.start()



    def my_web_callback(self, result):
        # This is the callback function

        # Result is a tuple of:
        #  sucess: True if web request submitted successfully
        #  result: The reponse from the web page
        success, response = result

        # As an example, I'm just showing a label if the request was submitted
        # successfully
        if success:
            txt = "Web request submitted successfully"

        else:
            txt = "Error submitting web request"

        self.callback_lbl.text = txt


class MainApp(App):
    def build(self):
        #imposto il colore dello sfondo
        Window.clearcolor = (255, 255, 255, 1)
        #Window.size=(500, 500)
        return Screen()

MainApp().run()
webtimeout.py

Code: Select all

#!/usr/bin/env python
from threading import Thread
import socket

import requests

class WebTimeout(Thread):
    '''An example class to show how web requests can be submitted in a
       background thread.

       Takes one mandatory parameter:
         address: The web address to request

       Takes six optional parameters:
         timeout:  Number of seconds until request timesour
         data:     Data to be submitted with request (e.g. via POST)
         headers:  Headers to be added to the request
         queue:    Queue object for thread-safe communication
         method:   GET, POST, DELETE, PUT
         callback: Function to be called when request ends
    '''

    def __init__(self, address, timeout=5, data=None, headers=None, queue=None,
                 method="GET", callback=None):
        Thread.__init__(self)
        self.q = queue
        self.timeout = timeout
        self.address = address
        self.data = data
        self.headers = headers
        self.method = method.lower()
        self.callback = callback

    def _sendRequest(self):
        '''Method to send the request. Returns a tuple
               (success, result)

           where:
             success: (Boolean) True if request submitted successfully
             result:  Python dict/list if response if valid JSON, else text
                      of response body.
        '''
        # Check if the requested method (GET, POST etc) is valid
        try:
            req = getattr(requests, self.method)
        except AttributeError:
            return (False, "Invalid method")

        # Build the request and submit
        try:
            r = req(self.address,
                    data=self.data,
                    headers=self.headers,
                    timeout=self.timeout)

        # Handle a timeout event
        except (socket.timeout, requests.Timeout):
            return (False, "Timed out")

        # Handle a connection error
        except requests.ConnectionError:
            return (False, "Connection error")

        # Catch anything else that goes wrong
        # (it's bad practice to do this!)
        except:
            return (False, "Unknown error")

        # Check if the response is successful
        if r.status_code != 200:
            return (False, "Response code {}".format(r.status_code))

        # See if the response is a JSON object
        try:
            response = r.json()
        # If not, try getting the text
        except requests.compat.json.JSONDecodeError:
            response = r.text
        # Naughty...
        except:
            response = "Some other error"
        finally:
            return (True, response)

    def run(self):
        '''This is the method that's run when the start() method is called.'''

        # submit the web request
        result = self._sendRequest()

        # If we've got a queue object, add the response to the queue
        # where it can be read via the get() method in the main thread
        if self.q:
            self.q.put(result)

        # If we've got a callback function, call it.
        if self.callback:
            self.callback(result)
The webtimeout script has some functionality (Queue) that you may not need. However, if you're going to have lots of background worker threads, Queues can be very useful.

I've put notes on the code to try and explain how it works.

Let me know how you get on.

Edit: you'll need to have the "requests" module installed for this.
RPi Information Screen: plugin based system for displaying weather, travel information, football scores etc.

paolojo
Posts: 117
Joined: Mon Oct 26, 2015 3:32 pm

Re: Multiprocessing on Raspberry

Fri Dec 18, 2015 4:12 pm

Hi Paraguayo,
sorry if I haven't still replied to you but I had a little problem with my pc and I have still not tried your code.
I'm waiting for a new pc; I'll try the code as soon as I received it.
have a nice weekend

paolojo
Posts: 117
Joined: Mon Oct 26, 2015 3:32 pm

Re: Multiprocessing on Raspberry

Mon Feb 15, 2016 5:12 pm

Hi,
I'm trying to understand WebTimeout.py code...but it is quite difficult for me because I don't know very well python language. :oops:
In your opinion, is it possibile to implement the same function in C language?
Thank you

User avatar
elParaguayo
Posts: 1943
Joined: Wed May 16, 2012 12:46 pm
Location: London, UK

Re: Multiprocessing on Raspberry

Mon Feb 15, 2016 5:23 pm

No idea. I don't know C!

Which bit of my code are you having problems with? It may be easier for me to explain how it works.
RPi Information Screen: plugin based system for displaying weather, travel information, football scores etc.

ejolson
Posts: 6324
Joined: Tue Mar 18, 2014 11:47 am

Re: Multiprocessing on Raspberry

Mon Feb 15, 2016 6:55 pm

paolojo wrote:Hi,
I'm trying to understand WebTimeout.py code...but it is quite difficult for me because I don't know very well python language. :oops:
In your opinion, is it possibile to implement the same function in C language?
Thank you
As the Python programming language itself is written in C, then anything Python can do must be possible with C. Note, however, that directly programming in C is likely to be more difficult than Python, especially when implementing communication protocols that require string handling. With all the error checks and comments the posted code looks overwhelming. Still it may be possible to use without full understanding. If you stay focused on one programming language, the meaning of such code should eventually be clear.

paolojo
Posts: 117
Joined: Mon Oct 26, 2015 3:32 pm

Re: Multiprocessing on Raspberry

Mon Feb 15, 2016 9:11 pm

Thank you for the advice!
Give me others few days to try to understand you code..and then iI'll write you my dubts :mrgreen:

Return to “Python”