ZMQ(java)-遇到的问题

本文探讨了ZeroMQ(ZMQ)中的线程通信机制,包括inproc与ipc的区别及应用实例。通过分析不同线程间的通信问题,揭示了ZMQ在多线程环境下可能遇到的问题及其解决方法。

我有一个疑惑,为什么我在本地编写的MD文件,排版看起来还算整齐,为什么到了优快云就乱了?何时才有大神出来替天行道,统一MD的语法!


  • publisher.bind(“ipc://weather”);—->Protocol not supported(0x87)
    • i将语句更改为publisher.bind(“inproc://weather”)
    • ipc是oses系统上的。windows不支持这个协议。
    • inproc的定义The in-process transport passes messages via memory directly between threads sharing a single ØMQ context.
    • inproc://name 此处的name是一个字符串,用来标识线程
  • inproc与ipc
    • inproc不是ipc的代替版。ipc是epoll下的进程通信。inporc是线程通信。ipc只在POSIX标准下的操作系统有。
  • inproc客户端收不到消息

  • 不知道为什么inporc收不到客户端的消息。源码如下

    public class Server2 {
        public static void main(String[] args) {
            new ServerThread().start();
            new ClientThread("10001").start();
        }
    }
    publisher.bind("inproc://weather");
    subscriber.connect("inproc://weather");
    
  • 不同的线程间必须共用同一个context.说实话ZMQ的context真的是……

  • 诡异的ZMQ线程

    简单的REP&REQ模式。只有一个客户端的时候服务器会有几个线程呢?如果按照轮询的方式,不管多少客户端接入,服务器只需要一个线程即可。
    使用java自带的性能分析器查看线程数

    • 一个普通的线程

      public class SimpleThread extends Thread{
          public static void main(String[] args) {
              new Thread(() -> { while(true) System.out.println("."); }).start();
          }
      }
      
    • 打印其线程内容

      • Reference Handler
      • Finalizer
      • Signal Dispatcher
      • Attach Listener
      • main
      • Thread-0
    • 除去守护线程,只有main和Thread-0

    • 下文中JServer.class运行后

    • 打印其线程内容
      • Reference Handler
      • Finalizer
      • Signal Dispatcher
      • Attach Listener
      • main
    • 所以它是用轮询的方式来处理消息。
  • 关于高级请求应答中的 ROUTER to N worker(REQ) 负载均衡的规则

    • P96的例子rtreq.c中描述代理者按照最近最少使用的规则为工人分发任务,为此我先将工人的每次工作时间修改为400毫秒,并打印了获取任务的工人ID顺序,一下是截取的前半部分的结果。从这个结果上来看,前十个是十个工人随机顺序来取的任务,从第十一个开始,按照规则,应该为第0个工人分发任务,但实际为第6个工人分发了任务。

    0 8 1 4 7 3 5 2 6 9 6 1 4 7 8 2 0 5 3 9 6 1 0 7 8 5 2 4 3 9 2 1 0 8 5 4 6 7 3 9 5 8 3 1 0 4 6 7 2

  • 根据书中的介绍,java版的例子在https://github.com/imatix/zguide2/tree/master/examples/Java,但是我发现有的例子不能运行。
  • 由于版本升级问题,早期版本的API发生了变化,有的被弃用,有的甚至被修改为别的名字。在本机上运行如下代码,可获取版本号。

    System.out.println(String.format("Version string: %s, Version int: %d", ZMQ.getVersionString(), ZMQ.getFullVersion()));
    我的输出:Version string: 4.1.4, Version int: 40104

  • while(1)的翻译方式。书中几乎每一处例子都有while(1)的循环,并在循环结束出进行了资源回收。而给出的java例子翻译为while(true)甚为不妥。如果翻译为while(true),则根据语法规则,由于while中并无结束循环的语句,因此后文不能再编写任何代码,也就是说当此处异常结束时,资源不能得到正确的回收。严谨的写法应该是while(!Thread.currentThread().isInterrupted())
  • API变化
    • mspoller.java
      ZMQ.Poller items = context.poller(2); 应更改为ZMQ.Poller items = new ZMQ.Poller(2);
    • msreader.java
      while((task = receiver.recv(ZMQ.NOBLOCK)) != null) 应更改为while((task = receiver.recv(ZMQ.DONTWAIT)) != null)
  • 语法错误
    • msgqueue.java
      ZMQQueue queue = new ZMQQueue(context, frontend, backend);的下一行应该添加一句 queue.run();
  • 有的API不存在。根据官方给出的例子mdcliapi.java
  • public ZMsg send(String service, ZMsg request) {
        request.push(new ZFrame(service));
        request.push(MDP.C_CLIENT.newFrame());
    > IDE给我给出如下提示:cannot resolve symbol 'MDP'.查看过zmq.jar之后,确实没有找到相关定义。我查看了多出的例子,都有这个存在,但是为什么我的就没有这个字段呢?网上的各处的jar都下载试过了,并没有这个。但是例子中都有这个,真是疑惑不解。
    
在C语言里,位左对齐右对齐一般在格式化输出时会用到,主要用于控制数据在输出时的位置。以下是相关介绍: ### 整型数据的左对齐右对齐 通过`printf`函数实现整型数据的左对齐右对齐右对齐是默认方式,在格式说明符`%`和`d`之间添加数字来规定输出宽度,若数字位数小于规定宽度,会在左边补空格;左对齐则需在数字前加`-`号,若数字位数小于规定宽度,会在右边补空格。 示例代码如下: ```c #include <stdio.h> int main() { // 右对齐。数字宽度为10,若不足10,在左边补足空格 printf("%10d\n", 1234); // 左对齐。数字宽度为10,若不足10,在右边补足空格 printf("%-10d\n", 1234); return 0; } ``` ### 不同输出长度的情况 当规定的输出宽度和数字实际位数不同时,有不同的处理方式。若规定宽度小于数字实际位数,会完整输出数字;若规定宽度大于数字实际位数,右对齐在左边补空格,左对齐在右边补空格。 示例代码如下: ```c #include <stdio.h> int main() { // -5是左对齐,输出长度为5。5是右对齐,输出长度为5 printf("%-5d %5d\n", 455, 455); printf("%-5d %5d\n", -123, -123); // 规定宽度小于实际位数,完整输出数字 printf("%-5d %5d\n", 987654, 987654); return 0; } ``` ### 其他数据类型的对齐 除整型外,其他数据类型也能实现左对齐右对齐。例如浮点数(`%f`)、字符串(`%s`)等,方法和整型一致。 示例代码如下: ```c #include <stdio.h> int main() { // 右对齐浮点数,宽度为10 printf("%10f\n", 3.14); // 左对齐浮点数,宽度为10 printf("%-10f\n", 3.14); // 右对齐字符串,宽度为10 printf("%10s\n", "hello"); // 左对齐字符串,宽度为10 printf("%-10s\n", "hello"); return 0; } ```
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值