比较内容: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; }
linux下消息队列性能比较(SVr4, POSIX, 信号量模拟消息队列)
于 2011-05-11 23:53:00 首次发布