2011-01-09 30 views
26

Tôi đã tò mò làm thế nào bạn có thể chạy một kịch bản python trong nền, lặp lại một nhiệm vụ mỗi 60 giây. Tôi biết bạn có thể đặt một cái gì đó trong nền bằng cách sử dụng &, là có hiệu lực cho trường hợp này?Hiệu quả Python Daemon

Tôi đã nghĩ đến việc thực hiện một vòng lặp, chờ 60 giây và tải lại, nhưng có điều gì đó khiến bạn cảm thấy khó chịu.

+1

Tùy thuộc vào những gì bạn muốn. Nếu bạn muốn lên lịch một tác vụ lặp lại thường xuyên, hãy xem cron. – Falmarri

Trả lời

7

Tôi nghĩ ý tưởng của bạn chính xác là những gì bạn muốn. Ví dụ:

import time 

def do_something(): 
    with open("/tmp/current_time.txt", "w") as f: 
     f.write("The time is now " + time.ctime()) 

def run(): 
    while True: 
     time.sleep(60) 
     do_something() 

if __name__ == "__main__": 
    run() 

Cuộc gọi tới time.sleep(60) sẽ đưa chương trình của bạn ngủ trong 60 giây. Khi thời gian đó kết thúc, hệ điều hành sẽ đánh thức chương trình của bạn và chạy hàm do_something(), sau đó đặt nó trở lại trạng thái ngủ. Trong khi chương trình của bạn đang ngủ, nó không làm gì hiệu quả lắm. Đây là một mô hình chung để viết các dịch vụ nền.

Để thực sự chạy này từ dòng lệnh, bạn có thể sử dụng &:

$ python background_test.py & 

Khi làm điều này, bất kỳ đầu ra từ kịch bản sẽ đi đến nhà ga giống như một trong những bạn bắt đầu nó từ. Bạn có thể chuyển hướng đầu ra để tránh điều này:

$ python background_test.py >stdout.txt 2>stderr.txt & 
+0

Cảm ơn người đàn ông, đây là chính xác những gì tôi đang tìm kiếm. Các bit và phần của chương trình tôi biết đến từ Javascript và cố gắng làm bất cứ điều gì trên một bộ đếm thời gian đã biến thành một cơn ác mộng! –

+1

Bạn cũng có thể muốn xem xét nohup (ví dụ: "nohup python background_test.py') giả sử bạn muốn daemon tiếp tục chạy sau khi bạn đăng xuất) – Foon

+1

Có một cách dễ dàng hơn để thực hiện việc này bằng cách sử dụng' python-daemon' "thư viện quy trình chuẩn daemon": http://stackoverflow.com/a/8375012/462302 – aculich

5

Sử dụng & trong vỏ có lẽ là cách đơn giản nhất đã chết như được mô tả của Greg.

Nếu bạn thực sự muốn tạo một Daemon mạnh mẽ, bạn sẽ cần phải nhìn vào lệnh os.fork().

Ví dụ từ Wikipedia:

#!/usr/bin/env python 
# -*- coding: utf-8 -*- 

import os, time 

def createDaemon(): 
    """ 
     This function create a service/Daemon that will execute a det. task 
    """ 

    try: 
    # Store the Fork PID 
    pid = os.fork() 

    if pid > 0: 
     print 'PID: %d' % pid 
     os._exit(0) 

    except OSError, error: 
    print 'Unable to fork. Error: %d (%s)' % (error.errno, error.strerror) 
    os._exit(1) 

    doTask() 

def doTask(): 
    """ 
     This function create a task that will be a daemon 
    """ 

    # Open the file in write mode 
    file = open('/tmp/tarefa.log', 'w') 

    # Start the write 
    while True: 
    print >> file, time.ctime() 
    file.flush() 
    time.sleep(2) 

    # Close the file 
    file.close() 

if __name__ == '__main__': 

    # Create the Daemon 
    createDaemon() 

Và sau đó bạn có thể đặt bất cứ công việc bạn cần bên trong khối doTask().

Bạn sẽ không cần khởi chạy ứng dụng này bằng cách sử dụng & và sẽ cho phép bạn tùy chỉnh thực thi thêm một chút nữa.

83

Thay vì viết daemon của riêng bạn, hãy sử dụng python-daemon để thay thế! python-daemon triển khai đặc tả daemon được xử lý tốt của PEP 3143, "Thư viện quy trình daemon chuẩn".

Tôi đã bao gồm mã ví dụ dựa trên câu trả lời được chấp nhận cho câu hỏi này và mặc dù mã trông gần như giống hệt nhau, nhưng nó có sự khác biệt cơ bản quan trọng. Nếu không có python-daemon, bạn sẽ phải sử dụng & để đặt quá trình của bạn ở chế độ nền và nohup và giữ cho quá trình của bạn không bị giết khi bạn thoát khỏi trình bao. Thay vào đó, điều này sẽ tự động tách khỏi thiết bị đầu cuối của bạn khi bạn chạy chương trình.

Ví dụ:

import daemon 
import time 

def do_something(): 
    while True: 
     with open("/tmp/current_time.txt", "w") as f: 
      f.write("The time is now " + time.ctime()) 
     time.sleep(5) 

def run(): 
    with daemon.DaemonContext(): 
     do_something() 

if __name__ == "__main__": 
    run() 

Để thực sự chạy nó:

python background_test.py 

Và lưu ý sự vắng mặt của & đây.

Ngoài ra, this other stackoverflow answer giải thích chi tiết về nhiều lợi ích khi sử dụng python-daemon.

+1

Bạn sẽ ngạc nhiên, nhưng tác giả và tác giả thư viện PEP là cùng một người. Vì vậy, có, thư viện thực hiện rất tốt rằng PEP :) – Reishin

+0

Bạn nói "câu trả lời xếp chồng khác này" nhưng liên kết đến một câu hỏi, không phải là câu trả lời. Câu trả lời được chọn cho câu hỏi bạn liên kết đến không sử dụng (tại thời điểm nhận xét này) python-daemon. Có thể bạn có nghĩa là https://stackoverflow.com/a/688448/117471? –

Các vấn đề liên quan