代码之家  ›  专栏  ›  技术社区  ›  Christopher Hunt

为什么googleappengine只支持单线程执行?

  •  12
  • Christopher Hunt  · 技术社区  · 14 年前

    有人知道为什么googleappengine只允许部署的应用程序执行一个线程吗?

    我个人认为,这与应用程序的可预测性有关,这样谷歌就可以更可靠地衡量其性能。谷歌网站上似乎没有任何关于单线程执行的理由,因此我的问题是。

    如果一个应用程序已经是多线程的,并且目前部署在一个VM上,那么考虑到这个限制,我很难迁移到云上。

    :我在下面标记了答案,因为由于水平缩放要求,不允许使用线程听起来很有道理。当然,所有线程都在同一个进程空间中执行,而且由于GAE可以为应用程序运行许多进程,因此很难共享线程。也就是说,我仍然认为每个进程有一个小的线程池会很有用,可能有助于将应用程序迁移到云端。我会要求这是一个特点。谢谢讨论!

    5 回复  |  直到 14 年前
        1
  •  12
  •   AshleyS    14 年前

    除了在Google App Engine中生成线程外,还有一种有限的替代方法,称为任务队列: http://code.google.com/appengine/docs/python/taskqueue/

    编辑

    http://code.google.com/appengine/docs/java/runtime.html#The_Sandbox

    跨应用程序的请求 多个web服务器,并防止 一个应用程序 另外,应用程序运行在 受限的“沙盒”环境。在 在这种环境下,应用程序可以 执行代码,存储和查询数据 请求并准备响应。

    正如其他人指出的,由于安全原因,不支持线程来沙盒应用程序。

    googleappengine中还有许多其他限制,迫使开发者创建可伸缩的应用程序。我认为任务队列只是这些限制中的另一个,因为与在处理HTTP请求的当前计算机上创建线程不同,任务被放入队列中,然后可以在队列中调度并由其他计算机执行。任务队列允许以可伸缩的方式在机器之间共享和分配工作。

        2
  •  7
  •   Nick Johnson    14 年前

    appengine使用了一个基于请求的执行模型,也就是说,所有的工作都限定在一个请求的范围内,不管是面对一个请求的用户,还是由另一个系统(如任务队列)初始化的用户。虽然可以在这种环境中使用线程,但多线程非常有用的大多数用例都涉及到长时间运行的进程(App Engine不是为这些进程而设计的),或者离线工作,在这种情况下,最好使用App Engine提供的可伸缩设施,如任务队列。

        3
  •  3
  •   mikerobi    14 年前

    我认为这是一个误导性的问题。应用程序引擎不允许应用程序生成线程,但应用程序引擎可能会启动应用程序的多个实例,或者使用某种线程或多进程请求处理程序。我不知道具体细节,但如果没有某种并行性,应用程序引擎将是一个非常无用的平台。

    我最初的回答错误地暗示线程不是一个有用的特性,它们有很多用途,但是大多数web开发人员并不在他们的应用程序中管理线程。线程通常在应用程序堆栈的较低级别进行管理。

        4
  •  2
  •   Kevin Lacquement    14 年前

    fork() 炸弹(或等效物)。而且,它大大简化了资源管理-谷歌只需要管理每个应用程序的一个线程的资源价值。

        5
  •  2
  •   Community Mofi    4 年前

    自提出此问题以来推出的一个新功能是 background threads .

    虽然常规线程在给定请求结束时加入(它们不能超过请求),但后台线程没有此限制。

    在手动或基本缩放实例上运行的代码可以启动一个后台线程,该线程可以比生成它的请求更长寿。这允许实例执行任意定期或计划的任务,或者在请求返回给用户后继续在后台工作。

    示例代码:

    from google.appengine.api import background_thread
    
    # sample function to run in a background thread
    def change_val(arg):
        global val
        val = arg
    
    if auto:
        # Start the new thread in one command
        background_thread.start_new_background_thread(change_val, ['Cat'])
    else:
        # create a new thread and start it
        t = background_thread.BackgroundThread(
            target=change_val, args=['Cat'])
        t.start()
    
        6
  •  0
  •   Suraj Vijayan    4 年前