cx_freeze使用sys.stdout.flush()和多处理

时间:2016-05-13 14:23:47

标签: python-3.x multiprocessing cx-freeze

我正在使用python 3.4.2和cx_freeze 4.3.4(全部64位) 我创建的程序在python下运行正常,但是当冻结时,它开始给我带来

的问题

sys.stdout.flush()
AttributeError:'TypeNone'对象没有属性'flush'

使用此处推荐的方法,我已设法将问题减少为Traceback消息,该消息在屏幕上闪烁几秒钟后消失。我该如何解决这个问题。 Windows Error Screen shot

只有在代码的多处理部分遇到 BREAK 命令时,才会调用stdout.flush。 任何关于将错误抑制/重定向到我的日志文件或帮助解决问题根源的建议都将不胜感激。

卡尔

class vDiags(tk.Tk):
    def __init__(self, *args, **kwargs):
        tk.Tk.__init__(self, *args, **kwargs)
        tk.Tk.wm_title(self, "Diagnostics")
        do stuff ............
        start_job()

def pinger(job_q, mdic, ping, result_q):
    devnull = open(os.devnull, 'w')
    logger.info("Starting Pinger")
    while True:
        ip = job_q.get()
        if ip is None:
            logger.info("No IP address, finishing early")
            break
        test_result = {}
        try:
            if is_valid_ipv4_address(ip) is True:
               do more stuff.........

def start_job():
    logger.info("Starting start_Job")
    pool_size = Variables.poll_size
    logger.info("Pool size %s" % pool_size)
    jobs = multiprocessing.Queue()
    logger.info("Jobs %s" % jobs)
    results = multiprocessing.Queue()
    logger.info("results %s" % results)
    manager = multiprocessing.Manager()
    logger.info("manager %s" % manager)
    manager_test_dict = manager.dict()
    logger.info("manager_test_dict %s" % manager_test_dict)
    for key, val in Variables.test_dic.items():
        manager_test_dict[key] = val
    pool = [multiprocessing.Process(target=pinger, args=(jobs, manager_test_dict, Variables.ping, results))
            for i in range(pool_size)
            ]
    for p in pool:
        logger.info("p in pool %s" % p)
        p.start()
    for i in Variables.source_ip:
        logger.info("Source IP:>  %s" % i)
        jobs.put(i)
    for p in pool:
        logger.info("p in pool (jobs) %s" % p)
        jobs.put(None)
    for p in pool:
        logger.info("p in pool (join) %s" % p)
        p.join()
    logger.info("Move Results to new Variable")
    logger.info(results.qsize())
    while not results.empty():
        Variables.test_result_raw = updatetree(Variables.test_result_raw, results.get())
    logger.info("Finished start_Job")


class fakestd(object):
    def write(self, string):
       logger.info("write %s" %string)
       pass

    def flush(self):
       logger.info("Flush %s " % self )
       pass

if __name__ == '__main__':
    #  **********  Main App **********
    sys.stdout = fakestd()
    sys.stderr = fakestd()
    multiprocessing.freeze_support()
    logger.info("tkinter Installed Version %s" % tk.TkVersion)
    app = vDiags()
    app.geometry("1280x720")
    app.mainloop()
#  **********  Main App **********

1 个答案:

答案 0 :(得分:0)

我现在正在解决这个问题(刚刚从线程迁移到多处理) 它似乎是多处理模块中的一个可疑错误。 multiprocessing.freeze_support()调用。

https://bugs.python.org/issue20607 据报道它仍然存在于py35中,但有可能在py源级固定。

从py34的角度来看,我需要更新的ONE文件是:

C:\ Python34 \ LIB \多\ process.py

 diff -u process_orig.py process.py
--- process_orig.py     2016-12-12 12:42:01.568186800 +0000
+++ process.py  2016-12-12 12:37:28.971929900 +0000
@@ -270,8 +270,14 @@
             traceback.print_exc()
         finally:
             util.info('process exiting with exitcode %d' % exitcode)
-            sys.stdout.flush()
-            sys.stderr.flush()
+# ---------- JRB modify
+            #sys.stdout.flush() # jrb edit to fix cx_freeze
+            #sys.stderr.flush() # jrb edit to fix cx_freeze
+            if sys.stdout is not None:
+                sys.stdout.flush()
+            if sys.stderr is not None:
+                sys.stderr.flush()
+# ---------- JRB modify

         return exitcode