热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

[Erlang0076]ErlangShell一个怪问题

最近一直在忙,偶尔有点时间在读书,补充一下能量;最近在学习程序设计语言-实践之路非常感慨,之前误打误撞的一点所得原来有一个更系统,完整的知识体系;于是沉下心来,慢慢吸收.像北上广这样的

 

   最近一直在忙,偶尔有点时间在读书,补充一下能量;最近在学习 程序设计语言-实践之路 非常感慨,之前误打误撞的一点所得原来有一个更系统,完整的知识体系;于是沉下心来,慢慢吸收.像北上广这样的城市快速的代谢着我们的精力和知识,不容懈怠,不过倒也不必急躁,如果心浮气躁,效果必然大打折扣;抽时间整理一下最近的笔记,先从一个怪异的问题开始吧!

 

  在Erlang shell中我常常创建一个无限等待接收消息的进程来做一些测试,代码:spawn(fun() -> receive after infinity-> io:format("DONE!") end end).问题复现步骤:1.在Erlang Shell中启动这个进程之后 2.向该进程发送消息 3.由于没有消息提取的逻辑,该进程收到的消息就会积压在消息队列里面,可以通过erlang:process_info查看;首先使用Shell进程来试一下,可以看到结果是和我们的预期一致的:

 

 

23> [self()!abc || _<-lists:seq(1,20)].
[abc,abc,abc,abc,abc,abc,abc,abc,abc,abc,abc,abc,abc,abc,
abc,abc,abc,abc,abc,abc]
24> erlang:process_info(self()).      
[{current_function,{erl_eval,do_apply,6}},
{initial_call,{erlang,apply,2}},
{status,running},
{message_queue_len,20},
{messages,[abc,abc,abc,abc,abc,abc,abc,abc,abc,abc,abc,abc,
            abc,abc,abc,abc,abc,abc,abc,abc]},
{links,[<0.26.0>]},
{dictionary,[]},
{trap_exit,false},
{error_handler,error_handler},
{priority,normal},
{group_leader,<0.25.0>},
{total_heap_size,5168},
{heap_size,2584},
{stack_size,24},
{reductions,68319},
{garbage_collection,[{min_bin_vheap_size,46368},
                      {min_heap_size,233},
                      {fullsweep_after,65535},
                      {minor_gcs,16}]},
{suspending,[]}] 
   下面我们使用spawn(fun)的方式试一下,看下面的结果,在发送了两条消息之后查看进程状态,发现消息队列是空的!!!

 

Erlang R15B (erts-5.9) [source] [64-bit] [async-threads:0] [hipe] [kernel-poll:false]

Eshell V5.9  (abort with ^G)
1> P=spawn(fun() -> receive after infinity-> io:format("dONE!") end end).
<0.34.0>
2> P!abc.
abc
3> P!abcd.
abcd
4> erlang:process_info(P).
[{current_function,{erl_eval,receive_clauses,8}},
{initial_call,{erlang,apply,2}},
{status,waiting},
{message_queue_len,0},
{messages,[]},
{links,[]},
{dictionary,[]},
{trap_exit,false},
{error_handler,error_handler},
{priority,normal},
{group_leader,<0.25.0>},
{total_heap_size,233},
{heap_size,233},
{stack_size,10},
{reductions,26},
{garbage_collection,[{min_bin_vheap_size,46368},
                      {min_heap_size,233},
                      {fullsweep_after,65535},
                      {minor_gcs,0}]},
{suspending,[]}]

 

 
 难道是这样的写法在Erlang Shell中有问题?我就把这段代码放在一个测试模块中试一下:
-module(t).
-compile(export_all).

a() -> 
    receive 
         {Data}-> io:format("reveive Data :~p~n ",[Data]),
         a()
    after infinity ->
          io:format("Done!")
    end.

b() -> spawn(fun() -> receive after infinity-> io:format("dONE!") end end). 
 
运行上面的代码t:b(),发送消息,然后查看进程状态,$$$$~~~~~~,看到了没有,这种写法消息队列里面是可以看到积压的消息的!! 那么之前的写法,接收到的消息在哪里呢?

 

5> t:b().
<0.39.0>
6> v(5)!abc.
abc
7> v(5)!abcd.
abcd
8> erlang:process_info(v(5)).
[{current_function,{t,'-b/0-fun-0-',0}},
{initial_call,{erlang,apply,2}},
{status,waiting},
{message_queue_len,2},
{messages,[abc,abcd]},
{links,[]},
{dictionary,[]},
{trap_exit,false},
{error_handler,error_handler},
{priority,normal},
{group_leader,<0.25.0>},
{total_heap_size,233},
{heap_size,233},
{stack_size,0},
{reductions,2},
{garbage_collection,[{min_bin_vheap_size,46368},
                      {min_heap_size,233},
                      {fullsweep_after,65535},
                      {minor_gcs,0}]},
{suspending,[]}]

 

   消息有可能在哪里呢?还有一个办法,我们把stacktrace输出一下,从下面的结果中我们可以看到一点端倪:进程P的堆栈信息中y(2) [abcd,abc]就是之前我们香它发送的消息;查看一下t:b()进程,并没有看到类似的信息;通过对比,突破点应该在这里,但是苦于没有找到process_dsiplay输出信息的详细说明,难以继续了,记录于此,日后继续

9> bt(P).
Program counter: 0x00007f738b7d76c0 (erl_eval:receive_clauses/8 + 168)
CP: 0x0000000000000000 (invalid)
arity = 0

0x00007f738d11c2d0 Return addr 0x000000000084e1b8 ()
y(0)     []
y(1)     value
y(2)     [abcd,abc]
y(3)     {value,#Fun7.20862592>}
y(4)     {eval,#Fun24.20862592>}
y(5)     []
y(6)     {[{call,1,{remote,1,{atom,1,io},{atom,1,format}},[{string,1,"dONE!"}]}],[]}
y(7)     []
y(8)     infinity
ok
10> bt(v(5)).
Program counter: 0x00007f73852f7ec0 (t:'-b/0-fun-0-'/0 + 8)
CP: 0x000000000084e1b8 ()
arity = 0
ok
11> 

 

最后贴张图,今年银河印象的作品 车手

 

 

 

 


推荐阅读
  • 利用RabbitMQ实现高效延迟任务处理
    本文详细探讨了如何利用RabbitMQ实现延迟任务,包括其应用场景、实现原理、系统设计以及具体的Spring Boot实现方式。 ... [详细]
  • 使用WinForms 实现 RabbitMQ RPC 示例
    本文通过两个WinForms应用程序演示了如何使用RabbitMQ实现远程过程调用(RPC)。一个应用作为客户端发送请求,另一个应用作为服务端处理请求并返回响应。 ... [详细]
  • 深入解析Hadoop的核心组件与工作原理
    本文详细介绍了Hadoop的三大核心组件:分布式文件系统HDFS、资源管理器YARN和分布式计算框架MapReduce。通过分析这些组件的工作机制,帮助读者更好地理解Hadoop的架构及其在大数据处理中的应用。 ... [详细]
  • 今天发现Mysql的主从数据库没有同步先上Master库:mysqlshowprocesslist;查看下进程是否Sleep太多。发现很正常。showmaster ... [详细]
  • 本文介绍如何在C#中将GridView控件的内容保存为图片文件。通过代码示例,详细说明了创建位图、绘制图形并保存图像的步骤。 ... [详细]
  • 本文档汇总了Python编程的基础与高级面试题目,涵盖语言特性、数据结构、算法以及Web开发等多个方面,旨在帮助开发者全面掌握Python核心知识。 ... [详细]
  • 深入浅出TensorFlow数据读写机制
    本文详细介绍TensorFlow中的数据读写操作,包括TFRecord文件的创建与读取,以及数据集(dataset)的相关概念和使用方法。 ... [详细]
  • 本文详细探讨了Java中Volatile关键字的工作原理、优化技巧及其在实际开发中的应用场景,特别是在提高多线程环境下数据可见性和减少锁竞争方面的优势。 ... [详细]
  • 本文探讨了大型服务端开发过程中常见的几个误区,包括异步任务处理不当、日志同步模式使用、网络操作未设置超时、缓存命中率及响应时间未统计、单一缓存模式、分布式缓存加锁不当以及团队管理上的误区,旨在帮助开发者避免这些常见错误。 ... [详细]
  • ˂p优秀的马里奥YouprobablywanttomakethecreationoftheformuladynamicsoeachrowofCta ... [详细]
  • 本文探讨了Web开发与游戏开发之间的主要区别,旨在帮助开发者更好地理解两种开发领域的特性和需求。文章基于作者的实际经验和网络资料整理而成。 ... [详细]
  • 深度解析 Redis 消息队列的应用与优势
    本文深入探讨了消息队列的基本概念及其在Redis中的实现方式。通过分析消息队列的核心组件——消息、生产者和消费者,以及它与阻塞队列的主要区别,帮助读者更好地理解如何利用Redis消息队列提高应用性能。 ... [详细]
  • MapReduce原理是怎么剖析的
    这期内容当中小编将会给大家带来有关MapReduce原理是怎么剖析的,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。1 ... [详细]
  • 本章探讨了使用固定数组实现栈和队列的基本方法,以及如何通过这些基本结构来实现更复杂的操作,如获取栈中的最小值。此外,还介绍了如何利用栈来模拟队列的行为,反之亦然。 ... [详细]
  • 尽管PHP是一种强大且灵活的Web开发语言,但开发者在使用过程中常会陷入一些典型的陷阱。本文旨在列出PHP开发中最为常见的10种错误,并提供相应的预防建议。 ... [详细]
author-avatar
彼岸花芬芳
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有