python 에서 서브쓰레드를 정상종료해보자 

시그널은 메인쓰레드만 받을수 있다.

메인쓰레드에서 시그널을 받아 서브쓰레드에 이벤트로 플래그를 전달한다.


#!/usr/local/python2.6/bin/python
#-*- coding: utf-8 -*-
import threading
import time
import logging
import random
import Queue
import signal
import sys
logging.basicConfig(level=logging.DEBUG,
                    format='(%(threadName)-9s) %(message)s',)
 
BUF_SIZE = 10
q = Queue.Queue(BUF_SIZE)
e = threading.Event()
 
class ProducerThread(threading.Thread):
    def __init__(self, group=None, target=None, name=None,
                 args=(), kwargs=None, verbose=None):
        super(ProducerThread,self).__init__()
        self.target = target
        self.name = name
    def run(self):
        while not e.is_set():
            if not q.full():
                item = random.randint(1,10)
                q.put(item)
                logging.debug('Putting ' + str(item)
                              ' : ' + str(q.qsize()) + ' items in queue')
        logging.debug("end")
        return
 
class ConsumerThread(threading.Thread):
    def __init__(self, group=None, target=None, name=None,
                 args=(), kwargs=None, verbose=None):
        super(ConsumerThread,self).__init__()
        self.target = target
        self.name = name
    def run(self):
        while not e.is_set():
            if not q.empty():
                item = q.get()
                logging.debug('Getting ' + str(item)
                              ' : ' + str(q.qsize()) + ' items in queue')
        logging.debug("end")
        return
 
if __name__ == '__main__':
    p = ProducerThread(name='producer')
    c = ConsumerThread(name='consumer')
    p.setDaemon(True)
    c.setDaemon(True)
    p.start()
    c.start()
    try:
        while p.is_alive() and c.is_alive():
            time.sleep(1)
    except KeyboardInterrupt:
        e.set()
 
    p.join()
    c.join()


kill 커맨드로 2번 시그널을 메인쓰레드에 전달한다.

end 구문까지 정상적으로 처리가 되고 종료가 된다.


]# ps -ef | grep tqt.py
root     23927 13186 99 11:55 pts/0    00:00:10 /usr/local/python2.6/bin/python ./tqt.py
 
]# kill -2 23927
 
(producer ) Putting 1 : 1 items in queue
(consumer ) Getting 1 : 0 items in queue
(producer ) Putting 7 : 1 items in queue
(consumer ) Getting 7 : 0 items in queue
(producer ) Putting 5 : 1 items in queue
(consumer ) Getting 5 : 0 items in queue
(producer ) Putting 2 : 1 items in queue
(consumer ) Getting 2 : 0 items in queue
(producer ) Putting 1 : 1 items in queue
(consumer ) Getting 1 : 0 items in queue
(producer ) Putting 1 : 1 items in queue
(consumer ) Getting 1 : 0 items in queue
(producer ) Putting 2 : 1 items in queue
(consumer ) Getting 2 : 0 items in queue
(producer ) Putting 2 : 1 items in queue
(consumer ) Getting 2 : 0 items in queue
(producer ) Putting 2 : 1 items in queue
(consumer ) Getting 2 : 0 items in queue
(producer ) Putting 10 : 1 items in queue
(consumer ) end
(producer ) end


'Python' 카테고리의 다른 글

s3 example  (0) 2016.12.28
daemonizing  (0) 2016.12.22
pidlockfile.py for windows  (0) 2016.12.19
cygwin + ssh + rsync  (0) 2016.12.10
remove ^M(Carriage Return)  (0) 2016.11.30

윈도우 가상서버 디스크이미지(vhd) 파일을 복사해서 다른 Hyper-V  서비스에서 디스크 추가를할때


permission 에러가 발생하는 경우가 있다.


vm  SID 를 vhd 파일에 추가해줘야한다.


디렉토리는 Virtual Machines 그룹이 추가되어 있어야 한다.


https://support.microsoft.com/en-us/kb/2249906



import os

user_id = "vm001"

drv = os.path.join("C:\\", "vm_disks")

for file in os.listdir(os.path.join(drv, user_id, "Virtual Machines")):

    if file.endswith(".xml"):

        vm_id = os.path.splitext(file)[0]

        disk_dir = os.path.join(drv, user_id, "Virtual Hard Disks")

        for disk_file in os.listdir(disk_dir):

            if disk_file.endswith(".vhd"):

                cmd = "icacls \"%s\" /grant \"NT VIRTUAL MACHINE\\%s\":(F)" % (os.path.join(disk_dir, disk_file), vm_id)

                print cmd

                res = os.popen(cmd).read()

                print res



기존에 있던 lockfile.pidlockfile 모듈을 참조하여 pid 부분을 수정


import os

import errno

from win32com.client import GetObject


class PIDLockError(Exception):

    pass


class AlreadyLocked(PIDLockError):

    def __init__(self, path):

        self.path = path

        

    def __str__(self):

        return "%s is already locked" % self.path


class LockFailed(PIDLockError):

    def __init__(self, path):

        self.path = path


    def __str__(self):

        return "failed to create %s" % self.path


class PIDLockFile(object):

    def __init__(self, path):

        self.path = path


    def read_pid(self):

        return self.read_pid_from_pidfile()


    def is_locked(self):

        return os.path.exists(self.path)


    def i_am_locking(self):

        running_process = []

        wmi = GetObject('winmgmts:')

        processes = wmi.InstancesOf('win32_Process')

        for pro in processes:

            running_process.append(pro.Properties_('ProcessId').value)

            

        if self.is_locked():

            if self.read_pid() in running_process:

                return True

        return False


    def acquire(self):

        if not self.i_am_locking():

            self.break_lock()

            

        try:

            self.write_pid_to_pidfile()

        except OSError, exc:

            if exc.errno == errno.EEXIST:


                raise AlreadyLocked(self.path)

            else:

                raise LockFailed(self.path)

        else:

            return


    def release(self):

        self.remove_existing_pidfile()


    def break_lock(self):

        self.remove_existing_pidfile()

        

    def read_pid_from_pidfile(self):

        pid = None

        try:

            pidfile = open(self.path, 'r')

        except IOError:

            pass

        else:

            line = pidfile.readline().strip()

            try:

                pid = int(line)

            except ValueError:

                pass

            pidfile.close()

        return pid


    def write_pid_to_pidfile(self):

        pidfile_fd = os.open(self.path, os.O_CREAT | os.O_EXCL | os.O_WRONLY)

        pidfile = os.fdopen(pidfile_fd, 'w')

        pid = os.getpid()

        pidfile.write("%s\n" % pid)

        pidfile.close()        


    def remove_existing_pidfile(self):

        if self.is_locked(): os.remove(self.path) 



# example

import os

import traceback

import pidlockfile import PIDLockFile, PIDLockError


def main():

    pid_file = os.path.join("C:\\", "run", "run.pid")

    plock = PIDLockFile(pid_file)

    try:

        plock.acquire()

        print "hellow" 

        plock.release()

        

    except PIDLockError, exc:

        print exc

    except Exception, exc:

        print traceback.format_exc()

        

if __name__ == "__main__":

    main()



'Python' 카테고리의 다른 글

daemonizing  (0) 2016.12.22
Threading  (0) 2016.12.22
cygwin + ssh + rsync  (0) 2016.12.10
remove ^M(Carriage Return)  (0) 2016.11.30
sqlalchemy  (0) 2016.11.28

+ Recent posts