#include #include "shm_com.h"
int main()
{
int runnint = 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);
}
当我们运行这些程序,我们会得到下面的输出:
$ ./shm1 &
[1] 294
Memory attached at 40017000
$ ./shm2
Memory attached at 40017000
Enter some text: hello
You wrote: hello
waiting for client...
waiting for client...
Enter some text: Linux!
You wrote: Linux!
waiting for client...
waiting for client...
waiting for client...
Enter some text: end
You wrote: end
$
工作原理
第一个程序,shm1,创建共享内存段并其关联到他的地址空间。我们在共享内存的第一部分揭示了shared_use_st结构。这个结构有一个标
记,written_by_you,当数据可用时会设置这个标记。当设置了这个标记时,程序会读取文本,输出文本,并且清除标记来表示程序已经读取数据
了。我们使用一个特殊的字符串,end,来进行由循环中的退出。程序然后分离共享内存并且删除他。
第二个程序,shm2,获得并关联共享内存段,因为他使用相同的键值,1234。然后他提示用户输入一些文本。如果设置了written_by_you标
记,shm2就会知道客户端程序还没有读取前面输入的数据并且进行等待。当其他进程清除了这个标记,shm2会写入新的数据并且设置标记。他也使用字符串
end来结束并分离共享内存段。
注意,我们必须提供我们自己的,相当粗糙的同步标记,written_by_you,这会导致一个低效的忙等待。在实际的程序中,我们会传递一个消息,或者使用管道,或者使用IPC消息(我们会在稍后讨论),生成信息,或是使用信号量来在程序的读取与写入部分提供同步。