2

共有メモリを使用してメッセージを交換する2つのプロセスを持つアプリケーションを構築しようとしています...ご覧のとおり、共有メモリを要求し、それに構造体を配置しています。構造体は、文字列、ブールフラグ、および列挙値で構成されます。文字列はメッセージを保持する必要があります。フラグは、このメッセージが反対側に表示されたかどうかを通知する必要があります(メッセージが存在する場合、誰もメッセージを追加できないため)はメモリ内の未読メッセージです)いくつかの問題が発生しています1-文字列の文字列に到達できません.... 2-文字列をintに置き換えたときに、クライアント側で問題が発生しましたメモリに到達するために、これはコードです...

サーバー側:

#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <iostream>
#include <string>
#include <sys/wait.h>
using namespace std;
enum e {Server,Client};

struct chat             // struct that will reside in the memory
{


    bool ifread;        //boolian variable to determin if the message has been raed or not
    e who;
    char message[50];
    int msgl;


};

int main(void)
{
string temp;
int shmid;
//key_t key=ftok(".",'a');
key_t key=433;

if ((shmid = shmget(key, sizeof(chat), IPC_CREAT | 0666)) < 0)
{
cout<<"shmget"<<endl;
return(1);
}

chat *str ;
str = (chat *)shmat(shmid, NULL, 0);

pid_t pid;
pid=fork();
str->ifread==true;

str->who=Server;
if(pid==0)
{

    while(temp!="bye")
    {
        if(str->ifread==false && str->who==Client)
        {
            //cout<<"Client said : ";

            for(int i=0;i<str->msgl;i++)
            cout<<str->message[i];
    str->ifread==true;

        }

    }

}

else if (pid>0)
{
    while(temp!="bye")
    {
    getline(cin,temp);
    str->msgl=temp.length();
    if(str->ifread)
     {
        str->who=Server;
        for(int i=0;i<str->msgl;i++)
         {
            str->message[i]=temp.at(i);
         }

    str->who=Server;
    str->ifread==false;
      }

    else if (!str->ifread && str->who==Client)
       {
    sleep(1);
    waitpid(pid,NULL,0);
        }
}

}

shmctl (shmid, IPC_RMID, NULL);

}

クライアント側:

#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <iostream>
#include <string>
#include <sys/wait.h>
using namespace std;
enum e {Server,Client};

struct chat             // struct that will reside in the memory
{


    bool ifread;        //boolian variable to determin if the message has been raed or not
    e who;
    char message[50];
    int msgl;


};

int main(void)
{
string temp;
int shmid;
//key_t key=ftok(".",'a');
key_t key=433;

if ((shmid = s`hmget(key, sizeof(chat),  0666)) < 0)
{
cout<<"shmget"<<endl;
return(1);
}

chat *str ;
str = (chat *)shmat(shmid, NULL, 0);

pid_t pid;
pid=fork();


if(pid==0)
{

    while(temp!="bye")
    {
        if(str->ifread==false && str->who==Server)
        {
            //cout<<"Server said : ";

            for(int i=0;i<str->msgl;i++)
            cout<<str->message[i];
    str->ifread==true;

        }

    }

}

else if (pid>0)
{
    while(temp!="bye")
    {
    getline(cin,temp);
    str->msgl=temp.length();
    if(str->ifread)
     {
        str->who=Client;
        for(int i=0;i<str->msgl;i++)
         {
            str->message[i]=temp.at(i);
         }
    str->ifread=false;

      }

    else if (!str->ifread && str->who==Server)
       {
    sleep(1);
    //waitpid(pid,NULL,0);
        }
}

}

shmctl (shmid, IPC_RMID, NULL);

}

よろしくお願いします、そして悪い英語をお詫びします....。

編集:aixに感謝しますが、別の問題があります。つまり、int xを使用してそれらの間で番号を交換した場合でも、クライアントは最初に共有メモリからデータを取得できませんでした。サーバーが別の値を設定した場合でも、クライアントは最初に0を与え続けました。 、そしてしばらくすると、shmget();を呼び出すときにエラーが発生し始めました。

edit(2):いくつかの変更を行いましたが、まだ機能していません...。

Edit(3):問題は解決しましたみんなありがとう、フラグの順序が悪いことが判明しましたありがとうありがとう...

4

2 に答える 2

4

主な問題は、内部でstd::stringヒープ割り当てを使用することです。

この意味は

struct chat
{
   string  letter;

文字列全体を構造体に配置しません。文字列オブジェクトを配置しますが、必ずしも文字列に関連付けられた文字データである必要はありません。

これを修正する1つの方法は、に置き換えるstd::stringことchar[N]です。

一般に、ポインタや参照を含むもので共有メモリを使用する場合は、特に注意が必要です。

また、建設/破壊に関する複雑さを避けるために、それがPODchatであることを確認するのが最善かもしれません。

于 2012-05-03T10:33:09.340 に答える
1

すべてを最初から再作成するのではなく、既存のライブラリを使用することをお勧めします。

例:Boost.Interprocessメッセージキューを提供します。

キュー内のデータはPODであるか、プロセス間割り当てメカニズムを使用する必要があることに注意してください。可能であれば、構造を共有メモリに書き留める前に、構造をシリアル化することをお勧めします。この方法では、下位互換性と上位互換性を処理する方が簡単です。

于 2012-05-03T12:04:32.370 に答える