簡體   English   中英

system V 消息隊列 vs. posix 消息隊列測試

[英]system V message queue vs. posix message queue test

我測試了兩種情況:

  1. system V 消息隊列:使用msgsend()發送 1,000,000 條消息“hello”並使用msgget()從另一個進程獲取它們
  2. POSIX消息隊列:發送百萬消息“你好”與mq_send()並讓他們從另一個進程用mq_receive()

然后在這兩種情況下,我都計算了將消息發送到隊列的 CPU 處理時間。

  1. system V mq CPU push time: 0.8(sec)

  2. posix mq CPU 推送時間:1.4(秒)(!)

系統 V 的代碼:

#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <time.h>

#define EXPERIMENT_COUNT 100

clock_t start, end;
double cpu_time_useda_avg = 0;
double cpu_time_used;

struct mesg_buffer { 
    long mesg_type; 
    char mesg_text[100]; 
} message; 

int run_sending_app()
{
    key_t key; 
    int msgid; 

    // ftok to generate unique key 
    key = ftok("/var/tmp/progfile", 65); 

    // msgget creates a message queue 
    // and returns identifier 
    msgid = msgget(key, 0666 | IPC_CREAT); 
    message.mesg_type = 1; 

    // printf("Write Data : "); 
    // fgets(message.mesg_text, sizeof(message.mesg_text), stdin);

    strcpy(message.mesg_text, "hello");
    int e,i;

    for( e = 0; e < EXPERIMENT_COUNT; e++ )
    {
        start = clock();

        for(i = 0; i != 1000000; i++)
            msgsnd(msgid, &message, sizeof(message), 0); 

        end = clock();
        cpu_time_used = ((double) (end - start)) / CLOCKS_PER_SEC;

        printf("cpu_time_used = %f\n", cpu_time_used);

        cpu_time_useda_avg += cpu_time_used;
    }

    printf("cpu_time_useda_avg = %f\n", cpu_time_useda_avg/EXPERIMENT_COUNT);

    // // display the message 
    // printf("Data send is : %s \n", message.mesg_text); 

    return 0; 
}

int run_receiving_app()
{
    key_t key; 
    int msgid;

    // ftok to generate unique key 
    key = ftok("/var/tmp/progfile", 65); 

    // msgget creates a message queue 
    // and returns identifier 
    msgid = msgget(key, 0666 | IPC_CREAT); 

    while(1)
    {
        // msgrcv to receive message 
        msgrcv(msgid, &message, sizeof(message), 0, 0);
        // // display the message 
        // printf("Data Received is : %s \n",  
        //                 message.mesg_text); 
    }


    // to destroy the message queue 
    msgctl(msgid, IPC_RMID, NULL); 

    return 0; 
}

int main(int argc, char const *argv[])
{   
    if( argc > 1 )
        if( !strcasecmp(argv[1], "cli") )
            run_sending_app();
        else if( !strcasecmp(argv[1], "serv") )
            run_receiving_app();

    return 0;
}

Posix 的代碼:

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <errno.h>
#include <mqueue.h>
#include <time.h>

#define EXPERIMENT_COUNT 100

clock_t start, end;
double cpu_time_useda_avg = 0;
double cpu_time_used;

#define QUEUE_NAME  "/test_queue"
#define MAX_SIZE    1024
#define MSG_STOP    "exit"

#define CHECK(x) \
    do { \
        if (!(x)) { \
            fprintf(stderr, "%s:%d: ", __func__, __LINE__); \
            perror(#x); \
            exit(-1); \
        } \
    } while (0) \

int mq_run_server()
{
    mqd_t mq;
    struct mq_attr attr;
    char buffer[MAX_SIZE + 1];
    int must_stop = 0;

    /* initialize the queue attributes */
    attr.mq_flags = 0;
    attr.mq_maxmsg = 1000000;
    attr.mq_msgsize = MAX_SIZE;
    attr.mq_curmsgs = 0;

    /* create the message queue */
    // mq_unlink(QUEUE_NAME); exit(0);

    mq = mq_open(QUEUE_NAME, O_CREAT | O_RDONLY, 0644, &attr);
    CHECK((mqd_t)-1 != mq);

    do {
        ssize_t bytes_read;

        /* receive the message */
        bytes_read = mq_receive(mq, buffer, MAX_SIZE, NULL);
        CHECK(bytes_read >= 0);

        buffer[bytes_read] = '\0';
        if (! strncmp(buffer, MSG_STOP, strlen(MSG_STOP)))
        {
            must_stop = 1;
        }
        else
        {
            // printf("Received: %s\n", buffer);
        }
    } while (!must_stop);

    /* cleanup */
    CHECK((mqd_t)-1 != mq_close(mq));
    CHECK((mqd_t)-1 != mq_unlink(QUEUE_NAME));

    return 0;
}

int mq_run_client()
{
    mqd_t mq;
    char buffer[MAX_SIZE];

    /* open the mail queue */
    mq = mq_open(QUEUE_NAME, O_WRONLY);
    CHECK((mqd_t)-1 != mq);


    strcpy(buffer, "hello");
    int e,i;

    for( e = 0; e < EXPERIMENT_COUNT; e++ )
    {
        start = clock();

        for(i = 0; i != 1000000; i++)
            mq_send(mq, buffer, MAX_SIZE, 0);

        end = clock();
        cpu_time_used = ((double) (end - start)) / CLOCKS_PER_SEC;

        printf("cpu_time_used = %f\n", cpu_time_used);

        cpu_time_useda_avg += cpu_time_used;
    }

    printf("cpu_time_useda_avg = %f\n", cpu_time_useda_avg/EXPERIMENT_COUNT);


    // printf("Send to server (enter \"exit\" to stop it):\n");
    // 
    // do {
    //     printf("> ");
    //     fflush(stdout);

    //     memset(buffer, 0, MAX_SIZE);
    //     fgets(buffer, MAX_SIZE, stdin);

    //     /* send the message */
    //     CHECK(0 <= mq_send(mq, buffer, MAX_SIZE, 0));

    // } while (strncmp(buffer, MSG_STOP, strlen(MSG_STOP)));

    /* cleanup */
    CHECK((mqd_t)-1 != mq_close(mq));

    return 0;
}

int main(int argc, char const *argv[])
{
    if( argc > 1 )
        if( !strcasecmp(argv[1], "serv") )
            mq_run_server();
        else if( !strcasecmp(argv[1], "cli") )
            mq_run_client();

    return 0;
}

在這兩種情況下,如果我運行./a.out serv ,服務器端運行,如果我運行./a.out cli ,客戶端運行。

我的問題

為什么 Posix MQ 的性能比 System V MQ 低,而http://man7.org/linux/man-pages/man7/mq_overview.7.html說 Posix MQ 和 System V MQ 非常相似?!

嘗試改變:

    mq_send(mq, buffer, MAX_SIZE, 0);

    mq_send(mq, buffer, 104, 0);

或者

#define MAX_SIZE 104

這樣您就可以比較相同的數據量。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM