进程与线程

进程(Process):进程是资源分配的基本单位
线程(Thread):线程是程序执行的基本单位

异同点:

  • 进程拥有自己的资源空间,每启动一个进程,系统就会为它分配地址空间
  • 线程与CPU资源分配无关,多个线程共享同一进程内的资源,使用相同的地址空间
  • 一个进程可以包含若干个线程
  • 线程的调度与切换比进程快很多,同时创建一个线程的开销也比进程要小很多。
  • 线程之间的通信更方便,同一进程下的线程共享全局变量、静态变量等数据,而进程之间的通信需要以通信的方式(Inter Process Communication,IPC)进行。不过如何处理好同步与互斥是编写多线程程序的难点。
  • 进程与进程之间相对独立。多进程程序更健壮,多线程程序只要有一个线程死掉,整个进程也死掉了,而一个进程死掉并不会对另外一个进程造成影响,因为进程有自己独立的地址空间。

Godot中的线程安全

  • 修改场景树时(添加子节点等)
  • 处理碰撞图形

以上两个情况都会使得直接调用方法造成线程不安全。
错误信息:area_set_shape_disabled: Can't change this state while flushing queries. Use call_deferred() or set_deferred() to change monitoring state instead.

func spawn_circle(_position = null):
    var c = Circle.instance()
    if  !_position :
        var x = rand_range(-150, 150)
        var y = rand_range( -500, -400)
        _position = player.target.position + Vector2(x, y)
    add_child(c)  # 造成线程不安全的语句
    c.init(_position)
    
func _on_Jumper_captured(object):
    $Camera2D.position = object.position
    # 下行是线程不安全的。
    #spawn_circle()  

    # 改写为下行便为线程安全,不会报错
    call_deferred("spawn_circle")

call_deferred()

void call_deferred(method: String, ...)

Calls the method on the object during idle time. This method supports a variable number of arguments, so parameters are passed as a comma separated list. Example:
在空闲时间调用方法作用在当前节点上。

call_deferred("set", "position", Vector2(42.0, 0.0))

最后修改:2020 年 07 月 15 日
如果觉得我的文章对你有用,请随意赞赏