erlang进程退出时清扫的资源

ERTS要终止一个经常的时候调用一下函数

void
erts_do_exit_process(Process* p, Eterm reason)
{
    ErtsLink* lnk;
    ErtsMonitor *mon;
#ifdef ERTS_SMP
    erts_pix_lock_t *pix_lock = ERTS_PID2PIXLOCK(p->id);
#endif

    p->arity = 0; /* No live registers */
    p->fvalue = reason;
   
#ifdef ERTS_SMP
    ERTS_SMP_CHK_HAVE_ONLY_MAIN_PROC_LOCK(p);
    /* By locking all locks (main lock is already locked) when going
       to status P_EXITING, it is enough to take any lock when
       looking up a process (erts_pid2proc()) to prevent the looked up
       process from exiting until the lock has been released. */
    erts_smp_proc_lock(p, ERTS_PROC_LOCKS_ALL_MINOR);
#endif
   
    if (erts_system_profile_flags.runnable_procs && (p->status != P_WAITING)) {
    profile_runnable_proc(p, am_inactive);
    }

#ifdef ERTS_SMP
    erts_pix_lock(pix_lock);
    p->is_exiting = 1;
#endif
   
    p->status = P_EXITING;

#ifdef ERTS_SMP
    erts_pix_unlock(pix_lock);

    if (ERTS_PROC_PENDING_EXIT(p)) {
/* Process exited before pending exit was received... */
p->pending_exit.reason = THE_NON_VALUE;
if (p->pending_exit.bp) {
    free_message_buffer(p->pending_exit.bp);
    p->pending_exit.bp = NULL;
}
    }

    cancel_suspend_of_suspendee(p, ERTS_PROC_LOCKS_ALL);

    ERTS_SMP_MSGQ_MV_INQ2PRIVQ(p);
#endif

    if (IS_TRACED_FL(p,F_TRACE_PROCS))
trace_proc(p, p, am_exit, reason);

    erts_trace_check_exiting(p->id);

    ASSERT((p->trace_flags & F_INITIAL_TRACE_FLAGS) == F_INITIAL_TRACE_FLAGS);

   
    /* 清除进程用的定时器 */
    cancel_timer(p); /* Always cancel timer just in case */

    /* 清除bif定时器 */
    if (p->bif_timers)
erts_cancel_bif_timers(p, ERTS_PROC_LOCKS_ALL);

    /* 清除ETS 资源*/
    if (p->flags & F_USING_DB)
db_proc_dead(p->id);

#ifdef ERTS_SMP
    if (p->flags & F_HAVE_BLCKD_MSCHED)
erts_block_multi_scheduling(p, ERTS_PROC_LOCKS_ALL, 0, 1);
#endif

    /* 清除 DLL驱动资源 */
    if (p->flags & F_USING_DDLL) {
erts_ddll_proc_dead(p, ERTS_PROC_LOCKS_ALL);
    }

    /* 清除dist节点监控 */
    if (p->nodes_monitors)
erts_delete_nodes_monitors(p, ERTS_PROC_LOCKS_ALL);

    /*
     * The registered name *should* be the last "erlang resource" to
     * cleanup.
     */
    /* 清除名字登记 */
    if (p->reg)
(void) erts_unregister_name(p, ERTS_PROC_LOCKS_ALL, NULL, p->reg->name);


    {
int pix;

ASSERT(internal_pid_index(p->id) < erts_max_processes);
pix = internal_pid_index(p->id);

erts_smp_proc_tab_lock();
erts_smp_sched_lock();

#ifdef ERTS_SMP
erts_pix_lock(pix_lock);

ASSERT(p->scheduler_data);
ASSERT(p->scheduler_data->current_process == p);
ASSERT(p->scheduler_data->free_process == NULL);

p->scheduler_data->current_process = NULL;
p->scheduler_data->free_process = p;
p->status_flags = 0;
#endif
process_tab[pix] = NULL; /* Time of death! */
ASSERT(erts_smp_atomic_read(&process_count) > 0);
erts_smp_atomic_dec(&process_count);

#ifdef ERTS_SMP
erts_pix_unlock(pix_lock);
#endif
erts_smp_sched_unlock();

if (p_next < 0) {
    if (p_last >= p_next) {
p_serial++;
p_serial &= p_serial_mask;
    }
    p_next = pix;
}

erts_smp_proc_tab_unlock();
    }

    /*
     * All "erlang resources" have to be deallocated before this point,
     * e.g. registered name, so monitoring and linked processes can
     * be sure that all interesting resources have been deallocated
     * when the monitors and/or links hit.
     */

    mon = p->monitors;
    p->monitors = NULL; /* to avoid recursive deletion during traversal */

    lnk = p->nlinks;
    p->nlinks = NULL;
    p->status = P_FREE;
    erts_smp_proc_unlock(p, ERTS_PROC_LOCKS_ALL);
    processes_busy--;

    if ((p->flags & F_DISTRIBUTION) && p->dist_entry)
erts_do_net_exits(p->dist_entry, reason);

    /*
     * Pre-build the EXIT tuple if there are any links.
     */
    if (lnk) {
Eterm tmp_heap[4];
Eterm exit_tuple;
Uint exit_tuple_sz;
Eterm* hp;

hp = &tmp_heap[0];

exit_tuple = TUPLE3(hp, am_EXIT, p->id, reason);

exit_tuple_sz = size_object(exit_tuple);

{
    ExitLinkContext context = {p, reason, exit_tuple, exit_tuple_sz};
    erts_sweep_links(lnk, &doit_exit_link, &context);
}
    }

    {
ExitMonitorContext context = {reason, p};
erts_sweep_monitors(mon,&doit_exit_monitor,&context);
    }

    delete_process(p);

#ifdef ERTS_ENABLE_LOCK_CHECK
    erts_smp_proc_lock(p, ERTS_PROC_LOCK_MAIN); /* Make process_main() happy */
    ERTS_SMP_CHK_HAVE_ONLY_MAIN_PROC_LOCK(p);
#endif
}


这些资源是进程拥有的 它有义务释放这些资源。 所以如果发现某些资源被莫名其妙的清除,请检查是不是进程异常退出!


你可能感兴趣的:(.net,erlang,F#,UP,HP)