linux下消息队列性能比较(SVr4, POSIX, 信号量模拟消息队列)

    比较内容:main中创建一个接收线程,总共发送5*1024*1024*1024 =
5G的数据。发送5*1024*1024次,每次发送1024字节的数据。总共进行5次实验。

    实验数据:

    SVr4 消息队列:
    第一次:26.020s
    第二次:26.283s
    第三次:25.872s
    第四次:25.857s
    第五次:26.597s
    平均:26.126s

    POSIX 消息队列:
    第一次:25.273s
    第二次:26.141s
    第三次:25.214s
    第四次:25.240s
    第五次:25.504s
    平均:25.474s

    信号量模拟消息队列:
    第一次:23.916s
    第二次:23.936s
    第三次:23.973s
    第四次:24.137s
    第五次:23.923s
    平均:23.977s
     
    我的结论:
    既然POSIX消息队列要比SVr4消息队列要快,那么就用POSIX好了,除非要兼容旧的系统。POSIX比SVr4快了2.5%左右,可能是具体实现有差异吧。
    对于用信号量模拟的消息队列,主要是想验证一下手动实现的是不是会比库提供的消息队列要快很多,结果只比POSIX的快6.2%左右。
    最后,俺认为一般情况下要用POSIX的消息队列,旧系统用SVr4的消息队列。实在对性能需求很强烈的话就用信号量来模拟吧。

    实验程序:

SVr4:
#include "stdio.h" #include "stdlib.h" #include "pthread.h" #include "sys/types.h" #include "sys/ipc.h" #include "sys/msg.h" #define NTIMES 5*1024*1024 #define HANDLE_ERROR(x) / { if ((x) == -1) { / perror(#x); / exit(EXIT_FAILURE); } } struct msgbuf{ long int mtype; char mtext[1024]; }threadbuf, buf = { 1, "", }; int qid; void* threadfunc(void* para) { int i; for (i = 0; i < NTIMES; i++){ msgrcv(qid, &threadbuf, 1024, 0, 0); } return NULL; } int main() { key_t key; int i; pthread_t t1; struct msqid_ds msqds; HANDLE_ERROR(key = ftok(".", 'r')); HANDLE_ERROR(qid = msgget(key, IPC_CREAT | 00700)); HANDLE_ERROR(msgctl(qid, IPC_STAT, &msqds)); //printf("msg_qnum = %u/n", msqds.msg_qnum); //printf("msg_qbytes = %u/n", msqds.msg_qbytes); pthread_create(&t1, NULL, threadfunc, NULL); for (i = 0; i < NTIMES; i++){ HANDLE_ERROR(msgsnd(qid, &buf, 1024, 0)); }; pthread_join(t1, NULL); HANDLE_ERROR(msgctl(qid, IPC_RMID, NULL)); return 0; }

POSIX:

#include "stdio.h" #include "stdlib.h" #include "pthread.h" #include "fcntl.h" #include "sys/stat.h" #include "mqueue.h" #define NTIMES 5*1024*1024 mqd_t mymq; struct mq_attr mymqattr; struct mq_attr mqattr; void* threadfunc(void* para) { char buf[1024]; int i; for (i = 0; i < NTIMES; i++){ if (mq_receive(mymq, buf, 1024, NULL) == -1){ perror("mq_recvive"); exit(EXIT_FAILURE); } } return NULL; } int main() { pthread_t t1; int i; char buf[1024]; mymqattr.mq_flags = 0; mymqattr.mq_maxmsg = 10; mymqattr.mq_msgsize = 1024; mymqattr.mq_curmsgs = 0; mymq = mq_open("/mymq", O_RDWR | O_CREAT | O_EXCL, S_IRWXU, &mymqattr); if (mq_getattr(mymq, &mqattr) == -1){ perror("mq_getattr"); exit(EXIT_FAILURE); } //printf("mq_flags = %d/n", mqattr.mq_flags); //printf("mq_maxmsg = %d/n", mqattr.mq_maxmsg); //printf("mq_msgsize = %d/n", mqattr.mq_msgsize); //printf("mq_curmsgs = %d/n", mqattr.mq_curmsgs); if (mymq == -1){ perror("mq_open"); exit(EXIT_FAILURE); } pthread_create(&t1, NULL, threadfunc, NULL); for (i = 0; i < NTIMES; i++){ if (mq_send(mymq, buf, 1024, 0) == -1){ perror("mq_send"); exit(EXIT_FAILURE); } } pthread_join(t1, NULL); if (mq_close(mymq) == -1){ perror("mq_close"); exit(EXIT_FAILURE); } if (mq_unlink("/mymq") == -1){ perror("mq_unlink"); exit(EXIT_FAILURE); } return 0; }

信号量模拟消息队列:

#include "stdio.h" #include "stdlib.h" #include "string.h" #include "pthread.h" #include "semaphore.h" #include "assert.h" #define MAX_QUEUE_SIZE 10 #define NTIMES 5*1024*1024 sem_t sem_empty; sem_t sem_occupy; char queue[MAX_QUEUE_SIZE + 1][1024]; int front,rear; void insertQueue(char *buf, unsigned size) { sem_wait(&sem_empty); memcpy(queue[front], buf, size); front = (front + 1) % (MAX_QUEUE_SIZE + 1); sem_post(&sem_occupy); assert(front != rear); } void deleteQueue(char *buf, unsigned size) { sem_wait(&sem_occupy); assert(front != rear); memcpy(buf, queue[rear], size); rear = (rear + 1) % (MAX_QUEUE_SIZE + 1); sem_post(&sem_empty); } void* threadfunc(void* para) { char buf[1024]; int i; for (i = 0; i < NTIMES; i++){ deleteQueue(buf, 1024); } return NULL; } int main() { pthread_t t1; int i; char buf[1024]; front = 0; rear = 0; sem_init(&sem_occupy, 0, 0); sem_init(&sem_empty, 0, MAX_QUEUE_SIZE); pthread_create(&t1, NULL, threadfunc, NULL); for (i = 0; i < NTIMES; i++){ insertQueue(buf, 1024); } pthread_join(t1, NULL); sem_destroy(&sem_occupy); sem_destroy(&sem_empty); return 0; }
 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值