2

共有メモリpipe()に基づいて、システムコールをシミュレートするライブラリを実装しました。

これで、子プロセスを呼び出さなくても、コードを使用していないときでもコードは正常に機能します。fork()

私のライブラリは任意 int main()のプログラムで動作する必要があるため、ここでの基本的な問題は、セマフォによる変更は、mainプログラムではなくライブラリで行う必要があるということです。

図書館 :

これがライブラリです:

static int flag = FALSE;
static int mutex_init = 0;
static pthread_mutex_t lock;

#define BUFFER 4096
int my_new_finish()
{
    return 1;  // always successful
}


void error_out(const char *msg)
{
    perror(msg);
    exit(EXIT_FAILURE);
}

mainこれで、このライブラリは、を呼び出すプログラムを使用していないときに正常に機能しfork()ます。

しかし、私が使用するときfork()、すべての地獄のブレーキは緩みます。

例えば ​​:

#include <stdio.h>
#include <stdlib.h>
int main()

{
    int spd, pid, rb;
    char buff[4096];
    my_new_init();

    if (my_new_fifo("tmp_shm_pipe",0666) < 0)
    {
        perror("my_new_fifo");
        exit(1);
    }

    if (fork()) 
    {
        spd = my_new_open("tmp_shm_pipe", O_RDONLY, 0600);
        if (spd < 0)
        {
            perror("PARENT: my_new_open");
            exit(1);
        }
        rb = my_new_read(spd, buff, sizeof(buff));
        if (rb > 0)
            write(1, buff, rb);
    }

    else
    {
        spd = my_new_open("tmp_shm_pipe", O_WRONLY, 0600);
        if (spd < 0)
        {
            perror("SON: my_new_open");
            exit(1);
        }
        my_new_write(spd, "hello world!\n", sizeof("hello world!\n"));
    }

    my_new_close(spd);
    my_new_un_link("tmp_shm_pipe");
    my_new_finish();

    return 0;
}

私の質問は:

  1. main()与えられるプログラムを「知らない」場合、上記のライブラリでセマフォを使用するにはどうすればよいですか?

  2. main()(プログラムではなく)ライブラリにセマフォを入れようとしましたが、うまくいきませんでした。どうすれば正しくできるのか説明してもらえますか?

備考 :

  1. mainこれは単なる例であり、他にも数え切れないほどのmainプログラムが与えられる可能性があることに注意してください。

  2. これは宿題です

とても有難い

4

2 に答える 2

2

わかりました。あなたがコンセプト全体にどれほど精通しているかわからないので、最善を尽くします。

1)セマフォの最も適切な「正しい」場所は、読み取りおよび書き込み機能です。メモリセグメントのプロセスを同期するには、セマフォも共有メモリに配置する必要があります。(すべてのプロセスにアクセスできるようにするため)

http://pdfcast.org/download/semaphores-sharedmem.pdf

これは、サンプルのメインを使用して、セマフォを作成、使用、および破棄するための、英語でコメントされた優れたコード例を含むPDFです。タイトルはドイツ語ですが、Cでも英語でもないものは他にありません。

それがあなたのスキルにとって「低レベル」ではなく、役立つことを願っています^^

于 2012-07-19T08:04:45.113 に答える
2

関数my_new_initでは、共有メモリに共有セマフォンを作成する必要がありますが、1回だけ呼び出されるように、その周りにガードがあります。このガードは通常、モジュール静的(またはクラス静的)変数を使用してライブラリモジュール内にあります。

sem_t *my_semaphone;
static int init = 0;

int my_new_init()
{
    if (!init)
    {
        my_semaphone = mmap(NULL, sizeof *my_semaphone, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANONYMOUS, -1, 0);
        if (!sem_init(my_semaphone, 1, 1))
        {
            init = TRUE;
        }
        else
            perror("Sem_init");
    }
    return 1; // always successful
}

次に、上部のmy_new_readで:

ssize_t my_new_read(int spd, void *buf, size_t count)
{
    char array[4096];
    memset(array, '\0', 4096);
    ssize_t returnVal = 0;

    sem_wait(my_semaphone);    

そしてmy_new_writeで、何かを書いた後にセマフォンをリリースします。

    sem_post(my_semaphone);
    return returnVal;

データの準備が整う前にsem_waitが返される可能性があるため、上記の改善が必要になる場合があります。そのため、共有メモリセグメントの先頭で制御構造を使用することをお勧めします。

于 2012-07-19T08:19:52.403 に答える