zmq发布订阅性能初步测试

      使用版本4.2.5,因社区介绍说udp的还不成熟,所以发布订阅用tcp的。一般使用场景是跨机器的,为了消除不同机器之间时间差,采用了互为发布订阅者。发布者程序在主线程中作为发布者定时发送数据,每条数据发完之后sleep的目的是:订阅者没法那么快处理,会丢数据。订阅者收到数据后,在子线程中把数据再发送回去。发布者通过子线程来接收订阅者返回的数据。通过接收时间-发送时间=2倍的单向延迟。

      发布者pub.c

#include "zmq.h"
#include <iostream>
#include <string.h>
#include <assert.h>
#include <stdlib.h>     /* atoi */
#include <stdio.h>
#include <thread>         // std::this_thread::sleep_for
#include <chrono>         // std::chrono::seconds

int i = 0;
char subip[30] = {0};
uint64_t tback = 0;

static inline long get_nano_second()
{
	timespec ts = {0};
	clock_gettime(CLOCK_MONOTONIC, &ts);
	return (long)(1000000000UL * ts.tv_sec + ts.tv_nsec);
}

void foo() 
{
  // do stuff...
  void* context = zmq_ctx_new();
    assert(context != NULL);
 
    void* subscriber = zmq_socket(context, ZMQ_SUB);
    assert(subscriber != NULL);
 
    int ret = zmq_connect(subscriber, subip);
    assert(ret == 0);
 
    ret = zmq_setsockopt(subscriber, ZMQ_SUBSCRIBE, "", 0);
    assert(ret == 0);
	
    while(1)
    {
        char szBuf[1024] = {0};
        ret = zmq_recv(subscriber, szBuf, sizeof(szBuf) - 1, 0);
        if (ret > 0)
        {
            printf("i=%d  %s\n", i, szBuf);
			tback = get_nano_second();
			break;
        }
		else
			printf("zmq_recv=%d\n", ret);	
    }
    zmq_close(subscriber);
    zmq_ctx_destroy(context);
 
}

int main(int argc, char *argv[])
{
	int major, minor, patch;
	zmq_version(&major, &minor, &patch);
	printf("zmq version: %d.%d.%d\n", major, minor, patch);   
   
   int n = 10000, k = 50;
   char sip[30] = {0};
 
   if (argc > 1) n = atoi(argv[1]);
   if (argc > 2) k = atoi(argv[2]);
   if (argc > 3) 
	   strcpy(sip, argv[3]);
   else
	   strcpy(sip, "tcp://192.168.67.144:5555");
   
   if (argc > 4) 
	   strcpy(subip, argv[4]);
   
	void* context = zmq_ctx_new();
	/* Create a ZMQ_PUB socket */
	void *socket = zmq_socket (context, ZMQ_PUB);
	assert (socket);
	
	/* Bind it to a in-process transport with the address 'my_publisher' */
	int rc = zmq_bind (socket, sip); assert (rc == 0);
	
	
	std::thread first(foo);
	getchar();
	
	uint64_t t1 = 0, t2 = 0, tk = 0;
	int ret = 0;
	while (true) {
		++i;
		if (i == 1) t1 = get_nano_second();
		if (i == k) tk = get_nano_second();
        char szBuf[1024] = {0};
        snprintf(szBuf, sizeof(szBuf), "server i=%d", i);
		ret = zmq_send(socket, szBuf, strlen(szBuf) + 1, 0);
		
		
		printf("%d\n", i);
		if (i >= n) break;
		std::this_thread::sleep_for(std::chrono::microseconds(2));
	}
	t2 = get_nano_second();
	first.join();                // pauses until first finishes
	printf("t1=%ld\t t2=%ld\t tk=%ld  tback=%ld  t2-t1=%ld\n", t1, t2, tk, tback, tback-tk);
	zmq_close(socket);
	zmq_ctx_destroy(context);
	return 0;
}

订阅者sub.cpp

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <assert.h>
#include "zmq.h"
#include <stdlib.h>     /* atoi */ 
#include <string.h>
#include <iostream>

int main(int argc, char *argv[])
{
    
 
    void* context = zmq_ctx_new();
    assert(context != NULL);
 
    void* subscriber = zmq_socket(context, ZMQ_SUB);
    assert(subscriber != NULL);
 
	int n = 10000, k = 50;
	char sip[30] = {0};
	char pubip[30] = {0};
	if (argc > 1) n = atoi(argv[1]);
	if (argc > 2) k = atoi(argv[2]);
	if (argc > 3) 
	   strcpy(sip, argv[3]);
   else
	   strcpy(sip, "tcp://192.168.67.144:5555");
   
   if (argc > 4) 
	   strcpy(pubip, argv[4]);
   
    int ret = zmq_connect(subscriber, sip);
    assert(ret == 0);
 
    ret = zmq_setsockopt(subscriber, ZMQ_SUBSCRIBE, "", 0);
    assert(ret == 0);
	
	//---
	void* context_pub = zmq_ctx_new();
	/* Create a ZMQ_PUB socket */
	void *socket_pub = zmq_socket(context_pub, ZMQ_PUB);
	assert(socket_pub);
	int rc_pub = zmq_bind(socket_pub, pubip); assert(rc_pub == 0);
	
    
	int i = 0;
    while(1)
    {
        ++i;
        char szBuf[1024] = {0};
        ret = zmq_recv(subscriber, szBuf, sizeof(szBuf) - 1, 0);
        if (ret > 0)
        {
			
            printf("i=%d  %s\n", i, szBuf);
        }
		else
			printf("zmq_recv=%d\n", ret);
		
        if (i == k)
			zmq_send(socket_pub, szBuf, strlen(szBuf) + 1, 0);
		
		if (i >= n) break;
    }
    
    zmq_close(subscriber);
    zmq_ctx_destroy(context);
 
	zmq_close(socket_pub);
	zmq_ctx_destroy(context_pub);
    return 0;
}

编译:

g++ -std=c++11 pub.c -L./ -lzmq -lpthread -o pub

g++ -std=c++11 sub.cpp -L./ -lzmq -lpthread -o sub

分别放到两台机器运行

./pub 20000 19000 tcp://192.168.1.7:5550 tcp://192.168.1.8:5560
./sub 20000 19000 tcp://192.168.1.7:5550 tcp://192.168.1.8:5560	

一个来回的耗时350us左右,单趟约等于175us。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值