现在的位置: 首页 > 综合 > 正文

Linux下共享内存示例

2018年03月18日 ⁄ 综合 ⁄ 共 2683字 ⁄ 字号 评论关闭

首先创建一个公共的头文件 shm_com.h:

<span style="font-size:12px;">#define TEXT_SZ 2048

typedef struct shared_use_st {
    int written_by_you;
    char some_text[TEXT_SZ];
};
</span>


创建消费者程序 shm1.c :

<span style="font-size:12px;">#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>


#include <sys/shm.h>
#include "shm_com.h"

int main()
{
    int running = 1;
    void *shared_memory = (void *)0;
    struct shared_use_st *shared_stuff;
    int shmid;

    srand((unsigned int) getpid());

    shmid = shmget( (key_t)1234, sizeof(struct shared_use_st), 0666|IPC_CREAT);
    printf("shmid = %d\n", shmid);
    if( -1 == shmid ) {
        fprintf(stderr, "shmget failed\n");
        exit( EXIT_FAILURE );
    }

    shared_memory = shmat( shmid, (void *)0, 0 );
    if( (void *) -1 == shared_memory ) {
        fprintf(stderr, "shmat failed\n");
        exit( EXIT_FAILURE );
    }

    printf("Memory attached at %X\n", (int)shared_memory);

    shared_stuff = (struct shared_use_st *)shared_memory;
    shared_stuff -> written_by_you = 0;
    while( running ) {
        if( shared_stuff->written_by_you ) {
            printf("You wrote: %s\n", shared_stuff->some_text);
            sleep( rand() % 4);
            shared_stuff->written_by_you = 0;
            if( strncmp(shared_stuff->some_text, "end", 3) == 0 ) 
                running = 0;
        }
    }

    if( -1 == shmdt(shared_memory) ) {
        fprintf(stderr, "shmdt failed\n");
        exit( EXIT_FAILURE );
    }

    if( -1 == shmctl(shmid, IPC_RMID, 0) ) {
        fprintf(stderr, "shmctl(IPC_RMID) failed\n");
        exit( EXIT_FAILURE );
    }

    exit( EXIT_SUCCESS );
}</span>


创建生产者程序 shm1.c :

<span style="font-size:12px;">#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>

#include <sys/shm.h>
#include "shm_com.h"

int main()
{
    int running = 1;
    void *shared_memory = (void *)0;
    struct shared_use_st *shared_stuff;
    char buffer[BUFSIZ];
    int shmid;

    shmid = shmget((key_t)1234, sizeof(struct shared_use_st), 0666|IPC_CREAT);
    printf("shmid = %d\n", shmid);
    if( -1 == shmid ) {
        fprintf(stderr, "shmget failed\n");
        exit( EXIT_FAILURE );
    }

    shared_memory = shmat(shmid, (void *)0, 0 );
    if( (void *) -1 == shared_memory ) {
        fprintf(stderr, "shmat failed\n");
        exit( EXIT_FAILURE );
    }

    printf("Memory attached at %X\n", (int)shared_memory );
    shared_stuff = (struct shared_use_st *)shared_memory;
    while( running ) {
        while( 1 == shared_stuff->written_by_you ) {
            sleep(1);
            printf("waiting for client...\n");
        }

        printf("Enter some text: ");
        fgets( buffer, BUFSIZ, stdin );

        strncpy( shared_stuff->some_text, buffer, TEXT_SZ);
        shared_stuff->written_by_you = 1;

        if( strncmp(buffer, "end", 3) == 0 ) {
            running = 0;
        }
    }

    if( -1 == shmdt(shared_memory) ) {
        fprintf(stderr, "shmdt failed\n");
        exit( EXIT_FAILURE );
    }

    exit( EXIT_SUCCESS );
}</span>


测是结果如下:

[zhang@localhost document]$ ./shm1 &
[1] 4989
[zhang@localhost document]$ shmid = 2326548
Memory attached at A475A000
./shm2
shmid = 2326548
Memory attached at E146F000
Enter some text: hey man
You wrote: hey man

waiting for client...
Enter some text: Linux
You wrote: Linux

waiting for client...
Enter some text: end
You wrote: end

注意:这里我们看到同一段物理内存在两个进程中映射的虚拟地址并不相同,也都不一定等于真正的物理内存的地址。

这里同步手段比较低级低效,在实际编程中,应该使用信号两或通过传递消息(使用管道或者IPC消息)、生成信号的方法来提供应用程序读、写部分之间的一种更有效率的同步机制。

抱歉!评论已关闭.