안드로이드용 프리 백신이 공개되었네요. 아직 전 옴니아 유저라 사용해 보진 못했지만 ㅡ_-+
항상 바이러스때문에 안드로이드 폰에 대해 우려하셨던 분들은 사용해 보시길 바랍니다.
현재 적용되는 버젼은 Android 2.1.x, 2.2.x, or 2.3.x 이며 안드로이드 마켓을 이용하시면 됩니다.
If you have a process that you want to do several things at the same time, threads may be the answer for you. They let you set up a series of processes (or sub-processes) each of which can be run independently, but which can be brought back together later and/or co-ordinated as they run.
For many applications, threads are overkill but on some occasions they can be useful.
A PYTHON APPLICATION WHERE THREADS WOULD HELP
Let's say that you want to check the availability of many computers on a network ... you'll use ping. But there's a problem - if you "ping" a host that's not running it takes a while to timeout, so that when you check through a whole lot of systems that aren't responding - the very time a quick response is probably needed - it can take an age.
Here's a Python program that "ping"s 10 hosts in sequence.
for host in range(60,70):
ip = "192.168.200."+str(host)
pingaling = os.popen("ping -q -c2 "+ip,"r")
print "Testing ",ip,
sys.stdout.flush()
while 1:
line = pingaling.readline()
if not line: break
igot = re.findall(lifeline,line)
if igot:
print report[int(igot[0])]
print time.ctime()
Running that program, it works but it's a bit slow:
[trainee@buttercup trainee]$ python alive
Mon May 9 05:22:51 2005
Testing 192.168.200.60 No response
Testing 192.168.200.61 No response
Testing 192.168.200.62 No response
Testing 192.168.200.63 No response
Testing 192.168.200.64 No response
Testing 192.168.200.65 No response
Testing 192.168.200.66 Alive
Testing 192.168.200.67 No response
Testing 192.168.200.68 No response
Testing 192.168.200.69 No response
Mon May 9 05:23:19 2005
[trainee@buttercup trainee]$
That was 28 seconds - in other words, an extra 3 seconds per unavailable host.
THE SAME APPLICATION, WRITTEN USING PYTHON THREADS
I'll write the application and test it first ... then add a few notes at the bottom.
import os
import re
import time
import sys
from threading import Thread
class testit(Thread):
def __init__ (self,ip):
Thread.__init__(self)
self.ip = ip
self.status = -1
def run(self):
pingaling = os.popen("ping -q -c2 "+self.ip,"r")
while 1:
line = pingaling.readline()
if not line: break
igot = re.findall(testit.lifeline,line)
if igot:
self.status = int(igot[0])
for host in range(60,70):
ip = "192.168.200."+str(host)
current = testit(ip)
pinglist.append(current)
current.start()
for pingle in pinglist:
pingle.join()
print "Status from ",pingle.ip,"is",report[pingle.status]
print time.ctime()
And running:
[trainee@buttercup trainee]$ python kicking
Mon May 9 05:23:36 2005
Status from 192.168.200.60 is No response
Status from 192.168.200.61 is No response
Status from 192.168.200.62 is No response
Status from 192.168.200.63 is No response
Status from 192.168.200.64 is No response
Status from 192.168.200.65 is No response
Status from 192.168.200.66 is Alive
Status from 192.168.200.67 is No response
Status from 192.168.200.68 is No response
Status from 192.168.200.69 is No response
Mon May 9 05:23:39 2005
[trainee@buttercup trainee]$
3 seconds - much more acceptable than the 28 seconds that we got when we pinged the hosts one by one and waited on each.
HOW DOES IT WORK?
We're going to run code concurrently to ping each host computer and (being Python), we create an object for each of the concurrent tests (threads) we wish to run. Each of these objects inherits from the Thread class so that we can use all of the logic already written in Python to provide our parallelism.
Although the constructor builds the thread, it does not start it; rather, it leaves the thread based object at the starting gate. The start method on the testit object actually triggers it off - internally, the start method triggers the run method of the testit class and alse returns to the calling code. In other words, this is the point at which the parallel processing actually starts, and the run method is called indirectly (via a callback, in a similar way to sort and map make callbacks).
Once parallel processes have started, you'll want some way to bring the responses back together at the end and in this first simple example, I've used a join. Note that this is NOT the same join method that you have in the string class ;-)
A join waits for a run method to terminate. So, having spawned a series of 10 pings in our example, our code waits for them to finish .... and it waits in the order that they were started. Some will be queuing up and completed long before our loop of joins gets to them, but that doesn't matter!
LOOKING AHEAD - MORE ON THREADS
If you're going to be writing a threaded application, there are (broadly) two main approaches you can take. The example that I've shown above uses a separate thread to take each request through from beginning to end and all the threads have the same structure. An alternative strategy is to write a series of "worker" threads each of which performs a step in a multistep process, and have them passing data on to one another. It's the difference between having an employee to walk each order through your factory and having employees at a production line passing each job on.
Where you're running threads, you have to be very much aware of the effect they can have on one another. As soon as you have two workers, their work may interfere with one another and you get involved in synchronisation (locking) of objects to ensure that this doesn't happen.
Locking / synchronisation brings its own further complications in that you have to involve "deadlocks" where two threads both require two resources ... each grabs the first, then waits for the second which (because the other has it) never becomes available.
FOOTNOTES
We've used the operating system's ping process in this example program. Ping responses vary between operating systems and you may need to alter the ping command and regular expression to match the response. The example above has been tested on Fedora Core Linux.
Threading makes heavy use of Operating System capabilities and is NOT as portable (no matter what language you're programming in) than most code