5

メッセージ キューの使用方法を学習しているところですが、少し問題があります。テストを行うために、2 つの完全に別個のアプリケーションを使用しています。1 つは「送信側」で、もう 1 つは「受信側」です。

送信者を実行すると、15 個の文字列がパイプに送信されますが、その後、「リソースが一時的に利用できません」というエラーで失敗します。受信者側でメッセージを消費する必要があるだけですが、なぜ15メッセージしかないのですか? 大量のメッセージを送信する可能性があるため、これをもっと大きな数、たとえば 1000 程度に増やしたいと考えています。

メッセージ キューのサイズを 32767 に設定しようとしたので、少なくとも 31 になると予想していましたmsg_qbytesが、バッファできるメッセージの数とは関係ないようです。

送信者コードは次のようになります。

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

#define MESSAGE_SIZE 1024

typedef struct msgbuf
{
    long mtype;
    char mtext[MESSAGE_SIZE];
};

int main(int argc, char *argv[]) {
    int msgid;
    int ret;
    struct msqid_ds msg_settings;
    long key;
        struct msgbuf msg;

    key = strtol(argv[1], NULL, 10);
    // print the message queue ID for reading via msgrcv
    printf( "Getting message queue with key = %ld\n", key);
    usleep( 1000000);

    msgid = msgget( (key_t)key, 0666 | IPC_CREAT);

    if (msgid == -1) {
        perror("msgget failed with error");
        exit(EXIT_FAILURE);
    }

    // read in current queue settings and then set the new
    // queue size.
    ret = msgctl(msgid, IPC_STAT, &msg_settings);
    msg_settings.msg_qbytes = 32767;
    msgctl( msgid, IPC_SET, &msg_settings);

    while( 1) {
        msg.mtype = 1; // we'll always leave this as 1
        memset( &(msg.mtext), 0, MESSAGE_SIZE);
        sprintf( msg.mtext, "hi");
        printf( "Sending data: %s\n", msg.mtext);
        ret = msgsnd( 1, &msg, MESSAGE_SIZE, IPC_NOWAIT);
        usleep( 500000);
        if( ret == -1) {
            perror( "msgsnd failed\n");
    }

    printf( "leaving...\n");

    return EXIT_SUCCESS;
}

受信コードは次のようになります。

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>

#define MESSAGE_SIZE 1024

typedef struct msgbuf
{
    long mtype;
    char mtext[MESSAGE_SIZE];
};

int main(int argc, char *argv[]) {
    long int msgtyp = 1;
    int ret;
    size_t msgsz;
    struct msgbuf mymsg;

    int msgid;
    msgid = strtol(argv[1], NULL, 10);
    printf( "Reading message queue with ID = %d\n", msgid);
    usleep( 1000000);
    while( 1) {
        msgsz = (size_t)MESSAGE_SIZE;
        ret = msgrcv( msgid, &mymsg, msgsz, msgtyp, IPC_NOWAIT);
        if( ret == ENOMSG) {
            usleep( 100000);
            continue;
        }

        if( ret == -1) {
            perror( "msgrcv failed");
        } else {
            printf( "Read data: %s", mymsg.mtext);
            }

        usleep( 100000);
    }
    return EXIT_SUCCESS;
}
4

3 に答える 3