本文通过一个例子演示linux下c语言如何通过共享内存的方式进行进程间通信,这是一个生产者消费者的例子。
实例1
生产者1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
int main(void)
{
        int shm_id;
        int *share;
        int num;
        srand(time(NULL));
        shm_id = shmget(1234, getpagesize(), IPC_CREAT);
        if (shm_id == -1) {
                perror("shmget()");
                exit(1);
        }
        share = (int *)shmat(shm_id, 0, 0);
        while (1) {
                num = random() % 1000;
                *share = num;
                printf("write a random number %d\n", num);
                sleep(1);
        }
        return 0;
}
消费者1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
int main(void)
{
        int shm_id;
        int *share;
        shm_id = shmget(1234, getpagesize(), IPC_CREAT);
        share = (int *)shmat(shm_id, 0, 0);
        while (1) {
                sleep(1);
                printf("%d\n", *share);
        }
        return 0;
}
实例2
shm_com.h1
2
3
4
5
struct shared_use_st {
        int written_by_you;
        char some_text[TEXT_SZ];
};
consumer.c1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
int main(void)
{
        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);
        if (shmid == -1) {
                fprintf(stderr, "shmget failed\n");
                exit(EXIT_FAILURE);
        }
        shared_memory = shmat(shmid, (void *)0, 0);
        if (shared_memory == (void *)-1) {
                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", 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 (shmdt(shared_memory) == -1) {
                fprintf(stderr, "shmdt failed\n");
                exit(EXIT_FAILURE);
        }
        if (shmctl(shmid, IPC_RMID, 0) == -1) {
                fprintf(stderr, "shmctl(IPC_RMID) failed\n");
                exit(EXIT_FAILURE);
        }
        exit(EXIT_SUCCESS);
        return 0;
}
producer.c1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
int main(void)
{
        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);
        if (shmid == -1) {
                fprintf(stderr, "shmget failed\n");
                exit(EXIT_FAILURE);
        }
        shared_memory = shmat(shmid, (void *)0, 0);
        if (shared_memory == (void *)-1) {
                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 (shared_stuff->written_by_you == 1) {
                        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 (shmdt(shared_memory) == -1) {
                fprintf(stderr, "shmdt failed\n");
                exit(EXIT_FAILURE);
        }
        exit(EXIT_SUCCESS);
        return 0;
}