代码一:
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <signal.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <sys/sem.h>
#include <errno.h>//改正过的循环倒置输出字符串************************************************
union semval
{
int val;
};
int main(int argc,char const* argv[])
{
key_t key;
key=ftok("./a.txt",'A');
if(key<0)
{
perror("ftok err");
return -1;
}printf("key=%#x\n",key);
/
//2.创建或打开信号灯集
int semid=semget(key,128,IPC_CREAT|IPC_EXCL|0666);
//key值//信号灯数//访问权限
if(semid < 0)
{
if(errno == EEXIST)
{
semid=semget(key,128,0666);
}else
{
perror("semget err.");
return -1;
}
}else //只有新建时需要初始化信号灯。
{
//3.初始化灯 灯有两个:编号0 1
union semval value;//需要先定义共用体变量形式union semval
value.val=1;
semctl(semid,0,SETVAL,value);
//信号灯id//信号灯编号//
value.val=0;
semctl(semid,1,SETVAL,value);
}
printf("***\n");
//4.申请资源 p
struct sembuf op;
//
int shmid=shmget(key,128,IPC_CREAT|IPC_EXCL|0666);
if(shmid<0)
{
if(errno==EEXIST)
{
shmid=shmget(key,128,0666);
}
else
{
perror("shmget err");
return -1;
}
}printf("shimd=%d\n",shmid);
char *sp=(char*)shmat(shmid,NULL,0);
if(sp==(char*)-1)//
{
perror("shmat err");
return -1;
}
strcpy(sp,"this is a interesting program");
//strcpy(sp,"hello world");
char *p=NULL,*q=NULL;
char temp;
while(1)
{
if(semctl(semid,0,GETVAL)>0)//0号灯:1//1号灯:0//根据0号灯数值判断进入if语句
{
//printf("0:%d 1:%d\n",semctl(semid,0,GETVAL),semctl(semid,1,GETVAL));
p=sp;
q=sp+strlen(sp)-1;
while(p<q)
{
*p^=*q;
*q^=*p;
*p++^=*q--;
}
//printf("%s\n",sp);
// op.sem_num=1;//1号灯
// op.sem_op=1;//申请
// op.sem_flg=0;//阻塞
// semop(semid,&op,1);
//sleep(1);
op.sem_num=0;//0号灯//
op.sem_op=-1;//申请
op.sem_flg=0;//阻塞
semop(semid,&op,1);//11111
op.sem_num=1;//1号灯//最后再更改信号灯1的值,防止8-shm-sem-w.c提前运行???
op.sem_op=1;//申请
op.sem_flg=0;//阻塞
semop(semid,&op,1);
//printf("0:%d 1:%d\n",semctl(semid,0,GETVAL),semctl(semid,1,GETVAL));
}
}
// 取消映射
shmdt(sp);
//销毁共享内存
shmctl(shmid,IPC_RMID,NULL);
return 0;
}
代码二:
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <signal.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <sys/sem.h>//
#include <errno.h>
union semval
{
int val;
};
int main(int argc,char const* argv[])
{
key_t key;
key=ftok("./a.txt",'A');
if(key<0)
{
perror("ftok err");
return -1;
}printf("key=%#x\n",key);
/
//2.创建或打开信号灯集
int semid=semget(key,128,IPC_CREAT|IPC_EXCL|0666);
//key值//信号灯数//访问权限
if(semid < 0)
{
if(errno == EEXIST)
{
semid=semget(key,128,0666);
}else
{
perror("semget err.");
return -1;
}
}else //只有新建时需要初始化信号灯。
{
//3.初始化灯 灯有两个:编号0 1
union semval value;//需要先定义共用体变量形式union semval
value.val=1;
semctl(semid,0,SETVAL,value);
//信号灯id//信号灯编号//
value.val=0;
semctl(semid,1,SETVAL,value);
}
printf("***\n");
//4.申请资源 p
struct sembuf op;
//
int shmid=shmget(key,128,IPC_CREAT|IPC_EXCL|0666);//必须加IPC_EXCL,不然会
if(shmid<0)
{
if(errno==EEXIST)
{
shmid=shmget(key,128,0666);
}
else
{
perror("shmget err");
return -1;
}
}printf("shimd=%d\n",shmid);
char *sp=(char*)shmat(shmid,NULL,0);
if(sp==(char*)-1)//
{
perror("shmat err");
return -1;
}
//int i=0;
while(1)
{
if(semctl(semid,1,GETVAL)>0)//0:0//1:1//根据一号等数值判断
{
//printf("0号灯:%d 1号灯:%d\n",semctl(semid,0,GETVAL),semctl(semid,1,GETVAL));//测试神技
// op.sem_num=0;//0号灯
// op.sem_op=1;//申请
// op.sem_flg=0;//阻塞
// semop(semid,&op,1);//1111111
sleep(1);//此处的sleep是必须的
printf("%s\n",sp);
if(strncmp(sp,"quit",4)==0)
break;
op.sem_num=1;//1号灯
op.sem_op=-1;//申请
op.sem_flg=0;//阻塞
semop(semid,&op,1);
op.sem_num=0;//0号灯//
op.sem_op=1;//申请
op.sem_flg=0;//阻塞
semop(semid,&op,1);//这里的1表示要操作的信号灯数,不是信号灯的编号
//printf("0号灯:%d 1号灯:%d\n",semctl(semid,0,GETVAL),semctl(semid,1,GETVAL));
}
}
// 取消映射
shmdt(sp);
//销毁共享内存
shmctl(shmid,IPC_RMID,NULL);
return 0;
}
使用方式:
打开两个代码所在终端;
ipcs查看是否有正在使用的共享内存;
ipcrm -s 共享内存号//删除共享内存;
两个终端分别运行gcc 代码1.c和gcc代码2即可;