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);

[size=large] [color=darkred]
/* 清除进程用的定时器 */
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);
[/color][/size]

{
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
}

[color=red]
这些资源是进程拥有的 它有义务释放这些资源。 所以如果发现某些资源被莫名其妙的清除,请检查是不是进程异常退出![/color]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值