#include <stdio.h>
#include <sys/shm.h>
#include <sys/sem.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include "common.h"
#define MAX_STRING 5000
typedef struct {
int semID;
int counter;
char string[MAX_STRING+1];
} MY_BLOCK_T;
int main(int argc, char *argv[])
{
int shmid, ret, i;
MY_BLOCK_T *block;
struct sembuf sb;
char user;
/* Make sure there's a command */
if(argc >= 2)
{
/* Create the shared memory segment and init it with the semaphore */
if(!strncmp(argv[1], "create", 6))
{
/* Create the shared memory segment and semaphore */
printf("Creating the shared memory segment\n");
/* Create the shared memory segment */
shmid = shmget(MY_SHM_ID, sizeof(MY_BLOCK_T), (IPC_CREAT | 0666));
/* Attach to the segment */
block = (MY_BLOCK_T *)shmat(shmid, (const void *)0, 0);
/* Initialize our write pointer */
block->counter = 0;
/* Create the semaphore */
block->semID = semget(MY_SEM_ID, 1, (IPC_CREAT | 0666));
/* Increment the semaphore */
sb.sem_num = 0;
sb.sem_op = 1;
sb.sem_flg = 0;
semop(block->semID, &sb, 1);
/* Now detach from the segment */
shmdt((void *)block);
}
else if(!strncmp(argv[1], "use", 3))
{
/* Use the segment */
/* Must specify also a letter (to write to the buffer) */
if(argc < 3)
exit(-1);
user = (char)argv[2][0];
/* Grab the shared memory segment */
shmid = shmget(MY_SHM_ID, 0, 0);
/* Attach to it */
block = (MY_BLOCK_T *)shmat(shmid, (const void *)0, 0);
for(i = 0; i < 2500; i++)
{
/* Give up the CPU temporarily */
sleep(0);
/* Grab the semaphore */
sb.sem_num = 0;
sb.sem_op = -1;
sb.sem_flg = 0;
if(semop(block->semID, &sb, 1) != -1)
{
/* Write our letter to the segment buffer(only we have the semaphore). This is our critical section */
block->string[block->counter++] = user;
/* Release the semaphore */
sb.sem_num = 0;
sb.sem_op = 1;
sb.sem_flg = 0;
if(semop(block->semID, &sb, 1) == -1)
{
printf("Failed to release the semaphore\n");
}
}
else
{
printf("Failed to acquire the semaphore\n");
}
}
/* We're done, unmap the shared memory segment. */
ret = shmdt((void *)block);
}
else if(!strncmp(argv[1], "read", 6))
{
/* Here, we'll read the buffer in the shared segment */
shmid = shmget(MY_SHM_ID, 0, 0);
if(shmid != -1)
{
block = (MY_BLOCK_T *)shmat(shmid, (const void *)0, 0);
/* Terminate the buffer */
block->string[block->counter+1] = 0;
printf("%s\n", block->string);
ret = shmdt((void *)block);
}
else
{
printf("Unable to read segment.\n");
}
}
else if(!strncmp(argv[1], "remove", 6))
{
shmid = shmget(MY_SHM_ID, 0, 0);
if(shmid >= 0)
{
block = (MY_BLOCK_T *)shmat(shmid, (const void *)0, 0);
/* Remove the semaphore */
ret = semctl(block->semID, 0, IPC_RMID);
/* Remove the shared segment */
ret = shmctl(shmid, IPC_RMID, 0);
if(ret == 0)
{
printf("Successfully removed the segment.\n");
}
}
}
else
{
printf("Unknown command %s\n", argv[1]);
}
}
return 0;
}
IPC机制---共享内存编程
最新推荐文章于 2024-08-27 17:48:14 发布