四、信号量通信
以下实现互斥操作
运行结果:
father got the sem
The returned value is 4424 in the father process(PID = 4423)
Child process will wait for some seconds ..
The returned value is 0 in the child process(PID = 4424)
六、消息队列
以下实现互斥操作
基础文件:
shm_com.c
union semun {
int val; /* Value for SETVAL */
struct semid_ds *buf; /* Buffer for IPC_STAT, IPC_SET */
unsigned short *array; /* Array for GETALL, SETALL */
struct seminfo *__buf; /* Buffer for IPC_INFO
(Linux-specific) */
};
int init_sem(int sem_id, int init_value)
{
union semun sem_union;
sem_union.val = init_value;
if(semctl(sem_id, 0, SETVAL, sem_union) == -1)
{
perror("Initialize semaphore");
return -1;
}
return 0;
}
int del_sem(int sem_id)
{
union semun sem_union;
if(semctl(sem_id, 0, IPC_RMID, sem_union) == -1) //
{
perror("Delete semaphore");
return -1;
}
}
/*
struct sembuf {
unsigned short sem_num; //semaphore number 信号量的编号
short sem_op; // semaphore operation 操作 -1为P操作, 1 为V操作
short sem_flg; // operation flags 通常设置SEM_UNDO 用来释放信号量
};
*/
int sem_p(int sem_id)
{
struct sembuf sem_b;
sem_b.sem_num = 0;
sem_b.sem_op = -1;
sem_b.sem_flg = SEM_UNDO;
if(semop(sem_id, &sem_b, 1)== -1) //semop 参数:第三个参数:操作信号的个数
{
perror("P operation");
return -1;
}
return 0;
}
int sem_v(int sem_id)
{
struct sembuf sem_b;
sem_b.sem_num = 0;
sem_b.sem_op = 1;
sem_b.sem_flg = SEM_UNDO;
if(semop(sem_id, &sem_b, 1)== -1)
{
perror("V operation");
return -1;
}
return 0;
}
测试程序
#include<sys/types.h>
#include<unistd.h>
#include<stdio.h>
#include<stdlib.h>
#include<sys/types.h>
#include<sys/ipc.h>
#include<sys/sem.h>
#include<sys/wait.h>
#include"./1.sem_com.c"
#define DELAY_TIME 3
int main(void)
{
pid_t result;
int sem_id;
sem_id = semget(ftok(".", 'a'), 1, 0666|IPC_CREAT);
init_sem(sem_id, 1);
result = fork();
if(result == -1)
{
perror("Fork\n");
}
else if(result == 0)
{
sleep(10);
sem_p(sem_id);
printf("Child process will wait for some seconds ..\n");
printf("The returned value is %d in the child process(PID = %d)\n",result, getpid());
sem_v(sem_id);
del_sem(sem_id);
}
else
{
sleep(3);
sem_p(sem_id);
printf("father got the sem\n");
printf("The returned value is %d in the father process(PID = %d)\n",result,getpid());
sem_v(sem_id);
waitpid(result,NULL,0);
}
exit(0);
}
运行结果:
father got the sem
The returned value is 4424 in the father process(PID = 4423)
Child process will wait for some seconds ..
The returned value is 0 in the child process(PID = 4424)
五、共享内存
简单实例:
#include<sys/types.h>
#include<sys/ipc.h>
#include<sys/shm.h>
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<unistd.h>
#include<sys/wait.h>
#include<sys/stat.h>
#define BUFFER_SIZE 2048
int main()
{
pid_t pid;
int shmid;
char * shm_addr;
char flag[] = "WROTE";
char buff[BUFFER_SIZE];
if((shmid = shmget(IPC_PRIVATE , BUFFER_SIZE, 0666)) < 0){ //用来创建共享内存
perror("shmget");
exit(1);
}else{
printf("Create shared-memory: %d\n", shmid);
}
system("ipcs -m"); //用来使用shell命令
pid = fork();
if(pid == -1){
perror("fork");
exit(1);
}else if(pid == 0){
if((shm_addr = shmat(shmid, 0, 0)) == (void*) -1){ //shmat:shmid 共享的标识。 0:共享内存映射到地址 0:表示可读写
perror("Child:shmat");
exit(1);
}else{
printf("Child:Attach shared-memory:%p\n", shm_addr);
}
system("ipcs -m");
while(strncmp(shm_addr, flag, strlen(flag))){
printf("Child: Wait for enable data...\n");
sleep(5);
}
strcpy(buff, shm_addr + strlen(flag));
printf("Child:Shared-memory:%s\n", buff);
if((shmdt(shm_addr)) < 0){
perror("shmdt");
exit(1);
}else{
printf("Child: Deattach shared-memory\n");
}
system("ipcs -m");
if(shmctl(shmid, IPC_RMID, NULL) == -1){
perror("Child:shmctl(IPC_RMID)\n");
exit(1);
}else{
printf("De;ete shared-memory\n");
}
system("ipcs -m");
}else{
if((shm_addr = shmat(shmid, 0, 0)) == (void *) -1){
perror("Parent:shmat");
exit(1);
}else{
printf("Parent:Attach shared-memory:%p\n", shm_addr);
}
sleep(1);
printf("\n Input some string:\n");
fgets(buff, BUFFER_SIZE, stdin);
strncpy(shm_addr + strlen(flag), buff, strlen(buff));
strncpy(shm_addr, flag, strlen(flag));
if((shmdt(shm_addr)) < 0){
perror("Parent:shmdt");
exit(1);
}else{
printf("Parent:Deattach shared-memory\n");
}
system("ipcs -m");
waitpid(pid, NULL, 0);
printf("Finished\n");
}
exit(0);
}
六、消息队列
msgrcv.c
#include<sys/types.h>
#include<sys/ipc.h>
#include<sys/msg.h>
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<string.h>
#define BUFFER_SIZE 512
struct message
{
long msg_type;
char msg_text[BUFFER_SIZE];
};
int main()
{
int qid;
key_t key;
struct message msg;
if((key = ftok(".", 'b')) == -1)//生成key
{
perror("ftok");
exit(-1);
}
if((qid = msgget(key, IPC_CREAT|0666)) == -1)
{
perror("msgget");
exit(1);
}
printf("Open queue %d\n", qid);
do
{
memset(msg.msg_text, 0, BUFFER_SIZE);
if(msgrcv(qid, (void*)&msg, BUFFER_SIZE, 0, 0) < 0)
{
perror("msgrcv");
exit(1);
}
printf("The message from process %d : %s", msg.msg_type, msg.msg_text);
}while(strncmp(msg.msg_text, "quit", 4));
if((msgctl(qid, IPC_RMID, NULL)) < 0)
{
perror("msgctl");
exit(1);
}
exit(0);
}
msgsnd.c
#include<sys/types.h>
#include<sys/ipc.h>
#include<sys/msg.h>
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<string.h>
#define BUFFER_SIZE 512
struct message
{
long msg_type;
char msg_text[BUFFER_SIZE];
};
int main()
{
int qid;
key_t key;
struct message msg;
if((key = ftok(".", 'b')) == -1){
perror("ftok");
exit(1);
}
if((qid = msgget(key, IPC_CREAT|0666)) == -1)
{
perror("msgget");
exit(1);
}
printf("Open queue %d\n", qid);
while(1){
printf("Enter some message to the queue:");
if((fgets(msg.msg_text, BUFFER_SIZE, stdin)) == NULL){
puts("no message");
exit(1);
}
msg.msg_type = getpid();
if((msgsnd(qid, &msg, strlen(msg.msg_text), 0)) < 0)
{
perror("message posted");
exit(1);
}
if(strncmp(msg.msg_text, "quit", 4) == 0)
break;
}
exit(0);
}