OSSIM项目研究记录(十六)

16 篇文章 1 订阅

2021SC@SDUSC


1、class ready

class _ready(Exception):
    pass

def which(filename):
    """Find the file 'filename' in the execution path. If no executable
       file is found, return None"""

    for dir in os.environ['PATH'].split(os.pathsep):
        fn=os.path.join(dir,filename)

        if os.path.exists(fn):
            if os.stat(fn)[0]&0111:
                return fn

    else:
        return None


    def Kill(self,signal=signal.SIGTERM):
        """Send a signal to the running subprocess.
           optional arguments:
               signal=SIGTERM: number of the signal to send.
                               (see os.kill)
           return value:
               see os.kill()
        """

        if self.status is None:
            # Only if it is not already finished
            return os.kill(self.pid,signal)

which函数在执行路径中查找文件“filename”。如果没有可执行文件就返回None
Kill向正在运行的子进程发送信号。如果自身状态为None就执行os.kill(self.pid,signal)
os.kill()一般用于直接Kill掉进程

2、class Task

管理异步子进程任务。
启动任务后,我们可以:

  • 询问它是否已经完成了
  • 等待它完成
  • 在等待时执行“空闲”任务(例如Tkinter的主循环)
  • 子进程终止
  • 使用特定信号终止子进程
  • 询问出口代码。

公共属性:None
公共方法:

  • __初始化:init
  • 运行: Run
  • 等待:Wait
  • 终止:Kill
  • 完成:Done
  • 状态:Status

2.1 def init

构造器


    def __init__(self,command):
        """Constructor.
           arguments:
               command: the command to run, in the form of a string,
                        or a tuple or list of words.
           """

        if type(command)==type(''):
            self.cmd=command
            self.words=command.split()

        elif type(command)==type([]) or type(command)==type(()):
            # Surround each word by ' '. Limitation: words cannot contain ' chars
            self.cmd="'"+"' '".join(command)+"'"
            self.words=tuple(command)

        else:
            raise error("command must be tuple, list, or string")

        self.pid=None
        self.status=None

2.2 def run

执行该进程。
这个方法应该只调用一次。
这个方法应该只调用一次。

可选参数:

  • usesh=0:如果为1,则运行“sh-c命令”,如果为0,则拆分命令变成文字,由我们自己来执行。如果usesh=1,“Kill”方法可能不起作用你想要(它会杀死“sh”进程,而不是命令)。
  • detach=0:如果为1,则运行“sh-c”命令&(不管“usesh”)。因为“sh”过程将立即终止,创建的任务将由继承“init”,这样你就可以放心地忘记它了。如果detach=1,Kill()、Done()和Status()将操作“sh”过程;没有办法知道这件事分离过程。
  • stdout=None:用作子进程的stdout的文件名。如果没有,将使用父级的标准输出。
  • stdin=None:用作子进程的stdin的文件名。如果没有,将使用父级的stdin。
  • stderr=None:用作子进程的stderr的文件名。如果没有,将使用父级的stderr。
  def Run(self,usesh=0,detach=0,stdout=None,stdin=None,stderr=None):
       
        if self.pid!=None:
            raise error("Second run on task forbidden")

        self.pid=os.fork()

        if not self.pid:
            for fn in range(3,256): # Close all non-standard files in a safe way
                try:
                    os.close(fn)

                except os.error:
                    pass

            if stdout: # Replace stdout by file
                os.close(1)
                i=os.open(stdout,os.O_CREAT|os.O_WRONLY|os.O_TRUNC,0666)

                if i!=1:
                    sys.stderr.write("stdout not opened on 1!\n")

            if stdin: # Replace stdin by file
                os.close(0)
                i=os.open(stdin,os.O_RDONLY)

                if i!=0:
                    sys.stderr.write("stdin not opened on 0!\n")

            if stderr: # Replace stderr by file
                os.close(2)
                i=os.open(stderr,os.O_CREAT|os.O_WRONLY|os.O_TRUNC,0666)

                if i!=2:
                    sys.stdout.write("stderr not opened on 2!\n")

            try:
                if detach:
                    os.execv('/bin/sh',('sh','-c',self.cmd+'&'))

                elif usesh:
                    os.execv('/bin/sh',('sh','-c',self.cmd))

                elif self.words[0]=='/':
                    os.execv(self.words[0],self.words)

                else:
                    os.execvp(self.words[0],self.words)

            except:
                print self.words
                sys.stderr.write("Subprocess '%s' execution failed!\n"%self.cmd)
                sys.exit(1)

        else:
            # Mother process
            if detach:
                # Should complete "immediately"
                self.Wait()

2.3 def wait

等待子进程终止。
如果进程已终止,此函数将立即返回。
返回值:子流程的退出状态(如果成功,则为0)。

  def Wait(self,idlefunc=None,interval=0.1):
      
        if self.status!=None:
            # Already finished
            return self.status

        if callable(idlefunc):
            while 1:
                try:
                    pid,status=os.waitpid(self.pid,os.WNOHANG)
                    if pid==self.pid:
                        self.status=status
                        return status
                    else:
                        idlefunc()
                        time.sleep(interval)
                except KeyboardInterrupt:
                    # Send the interrupt to the inferior process.
                    try:
                        self.Kill(signal=signal.SIGINT)
                    except OSError:
                        # Apparently the process has terminated?
                        pass
                except OSError:
                    # Apparently the process is unfindable?
                    print "WARNING: Unfindable process. Somebody else asked for my status!"
                    self.status=0
                    return 0
        elif idlefunc:
            raise error("Non-callable idle function")

        else:
            while 1:
                try:
                    pid,status=os.waitpid(self.pid,0)
                    self.status=status
                    return status
                except KeyboardInterrupt:
                    # Send the interrupt to the inferior process.
                    try:
                        self.Kill(signal=signal.SIGINT)
                    except OSError:
                        # Apparently the process has terminated?
                        pass
                except OSError:
                    # Apparently the process is unfindable?
                    print "WARNING: Unfindable process. Somebody else asked for my status!"
                    self.status=0
                    return 0

2.4 def Kill

向正在运行的子进程发送信号。
参数:要发送的信号的编号。

  def Kill(self,signal=signal.SIGTERM):
       
        if self.status is None:
            # Only if it is not already finished
            return os.kill(self.pid,signal)
        else:
            print "DBG> trying to send signal to finished program"


2.5 def Done

询问进程是否已完成。
返回值:

  • 1:流程已经完成了。
  • 0:流程尚未完成。

    def Done(self):
        if self.status!=None:
            return 1

        else:
            pid,status=os.waitpid(self.pid,os.WNOHANG)

            if pid==self.pid:
                #print "OK:",pid,status
                self.status=status
                return 1

            else:
                #print "NOK:",pid,status
                return 0

3、class attach


class Attach:
    def __init__(self,pid):
        self.pid=pid


    def Kill(self,signal=signal.SIGTERM):
        """Send a signal to the attached process.
           optional arguments:
               signal=SIGTERM: number of the signal to send.
                               (see os.kill)
           return value:
               see os.kill()
        """
        return os.kill(self.pid,signal)


    def Status(self):
        try:
            self.Kill(signal=0)

        except OSError:
            return 0 # Terminated (or owned by someone else)

        return None # Still running

4、总结

本文件作用为对任务和任务的子进程进行监控,对任务进行执行并等待结束,在收到KILL指令时,将杀死进程。最终返回任务的执行情况。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值