Linux下共享内存示例

首先创建一个公共的头文件 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消息)、生成信号的方法来提供应用程序读、写部分之间的一种更有效率的同步机制。

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。