153 lines
3.6 KiB
C
153 lines
3.6 KiB
C
/*************************************************************************
|
||
> File Name : ipc_share_mem_client.c
|
||
> Author : TL Song
|
||
> EMail : songtianlun@frytea.com
|
||
> Created Time : Mon 28 Dec 2020 03:54:50 PM CST
|
||
************************************************************************/
|
||
#include<stdio.h>
|
||
#include<stdlib.h>
|
||
#include<sys/shm.h> // shared memory
|
||
#include<sys/sem.h> // semaphore
|
||
#include<sys/msg.h> // message queue
|
||
#include<string.h> // memcpy
|
||
|
||
// 消息队列结构
|
||
struct msg_form {
|
||
long mtype;
|
||
char mtext;
|
||
};
|
||
|
||
// 联合体,用于semctl初始化
|
||
union semun
|
||
{
|
||
int val; /*for SETVAL*/
|
||
struct semid_ds *buf;
|
||
unsigned short *array;
|
||
};
|
||
|
||
// P操作:
|
||
// 若信号量值为1,获取资源并将信号量值-1
|
||
// 若信号量值为0,进程挂起等待
|
||
int sem_p(int sem_id)
|
||
{
|
||
struct sembuf sbuf;
|
||
sbuf.sem_num = 0; /*序号*/
|
||
sbuf.sem_op = -1; /*P操作*/
|
||
sbuf.sem_flg = SEM_UNDO;
|
||
|
||
if(semop(sem_id, &sbuf, 1) == -1)
|
||
{
|
||
perror("P operation Error");
|
||
return -1;
|
||
}
|
||
return 0;
|
||
}
|
||
|
||
// V操作:
|
||
// 释放资源并将信号量值+1
|
||
// 如果有进程正在挂起等待,则唤醒它们
|
||
int sem_v(int sem_id)
|
||
{
|
||
struct sembuf sbuf;
|
||
sbuf.sem_num = 0; /*序号*/
|
||
sbuf.sem_op = 1; /*V操作*/
|
||
sbuf.sem_flg = SEM_UNDO;
|
||
|
||
if(semop(sem_id, &sbuf, 1) == -1)
|
||
{
|
||
perror("V operation Error");
|
||
return -1;
|
||
}
|
||
return 0;
|
||
}
|
||
|
||
|
||
int main()
|
||
{
|
||
key_t key;
|
||
int shmid, semid, msqid;
|
||
char *shm;
|
||
struct msg_form msg;
|
||
int flag = 1; /*while循环条件*/
|
||
|
||
// 获取key值
|
||
if((key = ftok(".", 'z')) < 0)
|
||
{
|
||
perror("ftok error");
|
||
exit(1);
|
||
}
|
||
|
||
// 获取共享内存
|
||
if((shmid = shmget(key, 1024, 0)) == -1)
|
||
{
|
||
perror("shmget error");
|
||
exit(1);
|
||
}
|
||
|
||
// 连接共享内存
|
||
shm = (char*)shmat(shmid, 0, 0);
|
||
if((int)shm == -1)
|
||
{
|
||
perror("Attach Shared Memory Error");
|
||
exit(1);
|
||
}
|
||
|
||
// 创建消息队列
|
||
if ((msqid = msgget(key, 0)) == -1)
|
||
{
|
||
perror("msgget error");
|
||
exit(1);
|
||
}
|
||
|
||
// 获取信号量
|
||
if((semid = semget(key, 0, 0)) == -1)
|
||
{
|
||
perror("semget error");
|
||
exit(1);
|
||
}
|
||
|
||
// 写数据
|
||
printf("***************************************\n");
|
||
printf("* IPC *\n");
|
||
printf("* Input r to send data to server. *\n");
|
||
printf("* Input q to quit. *\n");
|
||
printf("***************************************\n");
|
||
system("/proc/$$/ns");
|
||
while(flag)
|
||
{
|
||
char c = 'r';
|
||
printf("Please input command: ");
|
||
//scanf("%c", &c);
|
||
switch(c)
|
||
{
|
||
case 'r':
|
||
printf("Data to send: ");
|
||
sem_p(semid); /*访问资源*/
|
||
//scanf("%s", shm);
|
||
strcpy(shm, "hello");
|
||
sem_v(semid); /*释放资源*/
|
||
/*清空标准输入缓冲区*/
|
||
while((c=getchar())!='\n' && c!=EOF);
|
||
msg.mtype = 888;
|
||
msg.mtext = 'r'; /*发送消息通知服务器读数据*/
|
||
msgsnd(msqid, &msg, sizeof(msg.mtext), 0);
|
||
break;
|
||
case 'q':
|
||
msg.mtype = 888;
|
||
msg.mtext = 'q';
|
||
msgsnd(msqid, &msg, sizeof(msg.mtext), 0);
|
||
flag = 0;
|
||
break;
|
||
default:
|
||
printf("Wrong input!\n");
|
||
/*清空标准输入缓冲区*/
|
||
while((c=getchar())!='\n' && c!=EOF);
|
||
}
|
||
}
|
||
|
||
// 断开连接
|
||
shmdt(shm);
|
||
|
||
return 0;
|
||
}
|