http://www.groad.net/bbs/read.php?tid-1135.html semget()
http://www.groad.net/bbs/read.php?tid-1136.html semop()
http://www.groad.net/bbs/read.php?tid-1137.html semctl()
http://www.groad.net/bbs/read.php?tid-1140.html shmget()
http://www.groad.net/bbs/read.php?tid-1141.html shmat() , shmdt()
http://www.groad.net/bbs/read.php?tid-1142.html shmctl()
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>
#include <sys/shm.h>
#include <errno.h>
#define SHM_SIZE 1024
/*semun 联合体最少要包含下面定义的3个元素*/
union semun {
int val;
struct semid_ds *buf;
unsigned short *array;
};
/*创建信号量函数*/
int createsem (const char *pathname, int proj_id, int members, int init_val)
{
key_t msgkey;
int index, sid;
union semun semopts;
/*创建key*/
if ((msgkey = ftok (pathname, proj_id)) == -1) {
perror ("ftok error!\n");
return (-1);
}
/*利用创建的key产生信号集标识符*/
if ((sid = semget (msgkey, members, IPC_CREAT | 0666)) == -1) {
perror ("semget call failed. \n");
return (-1);
}
/*初始化*/
semopts.val = init_val;
for (index = 0; index < members; index++) {
semctl (sid, index, SETVAL, semopts);
}
return (sid);
}
/*打开信号量*/
int opensem (const char *pathname, int proj_id)
{
key_t msgkey;
int sid;
if ((msgkey = ftok (pathname, proj_id)) == -1) {
perror ("ftok error!\n");
return (-1);
}
if ((sid = semget (msgkey, 0, IPC_CREAT | 0666)) == -1) {
perror ("semget call failed. \n");
return (-1);
}
return (sid);
}
/*P操作*/
int sem_p (int semid, int index)
{
struct sembuf buf = {0, -1, IPC_NOWAIT};
if (index < 0) {
perror ("index of array cannot equals a minus value!");
return (-1);
}
buf.sem_num = index;
if (semop (semid, &buf, 1) == -1) {
perror ("a wrong operation to semaphore occurred!");
return (-1);
}
return (0);
}
/*V操作*/
int sem_v (int semid, int index)
{
struct sembuf buf = {0, 1, IPC_NOWAIT};
if (index < 0) {
perror ("index of array cannot equals a minus value!");
return (-1);
}
buf.sem_num = index;
if (semop (semid, &buf, 1) == -1) {
perror ("a wrong operation to semaphore occurred!");
return (-1);
}
return 0;
}
/*删除信号集*/
int sem_delete (int semid)
{
return (semctl (semid, 0, IPC_RMID));
}
/*等待信号为1*/
int wait_sem (int semid, int index)
{
int second = 0;
while (semctl (semid, index, GETVAL, 0) == 0) {
sleep (1);
printf ("Can not enter the shared memory for %ds\n", second);
second += 1;
}
printf ("Can Enter The Shared Memory!\n");
return (1);
}
/*创建内存函数*/
int createshm (char *pathname, int proj_id, size_t size)
{
key_t shmkey;
int sid;
if ((shmkey = ftok (pathname, proj_id)) == -1) {
perror ("ftok error!\n");
return (-1);
}
if ((sid = shmget (shmkey, size, IPC_CREAT | 0666)) == -1) {
perror ("shmget call failed. \n");
return (-1);
}
return (sid);
}
#include "sharemem.h"
int main()
{
int semid, shmid;
int len;
char *shmaddr;
char write_str [SHM_SIZE];
/*创建共享内存*/
if ((shmid = createshm (".", 'm', SHM_SIZE)) == -1) {
exit (1);
}
/*附加共享内存到进程空间*/
if ((shmaddr = shmat (shmid, (char *)0, 0)) == (char *)-1) {
perror ("attach shared memory error!\n");
exit (1);
}
/*创建信号量集,这里信号量集中只有一个信号量(一般情况下也只需要一个)*/
if ((semid = createsem (".", 's', 1, 1)) == -1) {
exit (1);
}
while (1) {
wait_sem (semid, 0); /*等待信号量释放已进入共享内存区*/
sem_p (semid, 0); /*P操作*/
printf ("write: ");
fgets (write_str, 1024, stdin);
len = strlen (write_str) - 1;
write_str [len] = '\0';
strcpy (shmaddr, write_str); /*标准输入内容复制到共享内存区*/
sleep (10); /*测试信号量锁定:使reader处于阻塞状态*/
sem_v (semid, 0); /*V操作,释放信号量*/
sleep (10); /*等待 reader 进行读操作*/
}
}
#include "sharemem.h"
int main ()
{
int semid, shmid;
char *shmaddr;
/*得到由写者创建共享内存区的标识符*/
if ((shmid = createshm (".", 'm', SHM_SIZE)) == -1) {
exit (1);
}
/*attach 共享内存区到自己的进程空间*/
if ((shmaddr = shmat (shmid, (char *)0, 0)) == (char *)-1) {
perror ("attach shared memory error!\n");
exit (1);
}
/*得到信号量集标识符*/
if ((semid = opensem (".", 's')) == -1) {
exit (1);
}
while (1) {
printf ("reader: \n");
wait_sem (semid, 0); /*等待信号值1*/
sem_p (semid, 0); /*P操作*/
printf ("%s\n", shmaddr);
sleep (10); /*使 writer 处于阻塞状态*/
sem_v (semid, 0); /*V操作*/
sleep (10); /*等待 write 进行写操作*/
}
}
beyes@linux-beyes:~/C/share_memory> ./writer.exe
Can Enter The Shared Memory!
write:
beyes@linux-beyes:~/C/share_memory> ./writer.exe
Can Enter The Shared Memory!
write: hello reader!
Can Enter The Shared Memory!
write:
beyes@linux-beyes:~/C/share_memory> ./reader.exe
reader:
Can not enter the shared memory for 0s
Can not enter the shared memory for 1s
Can not enter the shared memory for 2s
Can not enter the shared memory for 3s
Can not enter the shared memory for 4s
Can not enter the shared memory for 5s
... ...
write: hello reader!
... ...
Can not enter the shared memory for 11s
Can not enter the shared memory for 12s
Can not enter the shared memory for 13s
Can not enter the shared memory for 14s
Can not enter the shared memory for 15s
Can not enter the shared memory for 16s
Can not enter the shared memory for 17s
Can not enter the shared memory for 18s
Can not enter the shared memory for 19s
Can not enter the shared memory for 20s
Can not enter the shared memory for 21s
Can Enter The Shared Memory!
hello reader!
欢迎光临 曲径通幽论坛 (http://www.groad.net/bbs/) | Powered by Discuz! X3.2 |