二值信号灯:值为0或1.与互斥锁类似,资源可用时值为1,不可用时值为0。
程序如下:
读端
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <errno.h>
#include <sys/sem.h>
#include <string.h>
#include <strings.h>
int wait(void)
{
int semid = -1;
int ret = -1;
key_t key = ftok("/home",2);
if ( -1 == key )
{
perror("ftok");
return -1;
}
semid = semget(key,2,0666|IPC_CREAT|IPC_EXCL);//获得信号灯ID。包含2个信号灯
if ( -1 == semid )
{
if( EEXIST == errno )
{
semid = semget(key,2,0666);
if (-1 == semid )
{
perror("semget");
return -1;
}
}else
{
perror("semget");
return -1;
}
}
struct sembuf buf;
bzero(&buf,sizeof(struct sembuf));
buf.sem_num = 0;
buf.sem_op = -1;//分配资源,p操作
buf.sem_flg = 0;
ret = semop(semid,&buf,1);//要操作一个信号灯,信号灯编号为0,操作时分配资源。使资源不可用。锁住
if ( -1 == ret )
{
perror("semop");
return -1;
}
}
char *addr=NULL;
void fun(int arg)
{
printf("%s ",addr);
}
int main(int argc,char **argv)
{
int ret = -1;
int shmid = -1;
//char *addr = NULL;
signal(2,fun);
key_t key = ftok("/",1);//获得key值
if ( -1 == key )
{
perror("ftok");
return -1;
}
shmid = shmget(key,4096,0666|IPC_CREAT|IPC_EXCL);//设置共享内存大小为4096
if ( -1 == shmid )
{
if (EEXIST == errno)
{
shmid = shmget(key,4096,0666);
if (-1 == shmid)
{
perror("shmget 2");
return -1;
}
}
else
{
perror("shmget");
}
}
addr = shmat(shmid,NULL,0);//获得共享内存的空间地址
if ( (void*)(-1) == addr )
{
perror("shmat");
return -1;
}
while(1)
{
wait();//v操作,分配资源,使共享内存资源减1;使资源不可用
//--
printf("%s",addr);
}
ret = shmdt(addr);
if ( -1 == ret )
{
perror("shmdt");
return -1;
}
printf("%ld ",key);
return 0;
}
#include <unistd.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <errno.h>
#include <sys/sem.h>
#include <string.h>
#include <strings.h>
int wait(void)
{
int semid = -1;
int ret = -1;
key_t key = ftok("/home",2);
if ( -1 == key )
{
perror("ftok");
return -1;
}
semid = semget(key,2,0666|IPC_CREAT|IPC_EXCL);//获得信号灯ID。包含2个信号灯
if ( -1 == semid )
{
if( EEXIST == errno )
{
semid = semget(key,2,0666);
if (-1 == semid )
{
perror("semget");
return -1;
}
}else
{
perror("semget");
return -1;
}
}
struct sembuf buf;
bzero(&buf,sizeof(struct sembuf));
buf.sem_num = 0;
buf.sem_op = -1;//分配资源,p操作
buf.sem_flg = 0;
ret = semop(semid,&buf,1);//要操作一个信号灯,信号灯编号为0,操作时分配资源。使资源不可用。锁住
if ( -1 == ret )
{
perror("semop");
return -1;
}
}
char *addr=NULL;
void fun(int arg)
{
printf("%s ",addr);
}
int main(int argc,char **argv)
{
int ret = -1;
int shmid = -1;
//char *addr = NULL;
signal(2,fun);
key_t key = ftok("/",1);//获得key值
if ( -1 == key )
{
perror("ftok");
return -1;
}
shmid = shmget(key,4096,0666|IPC_CREAT|IPC_EXCL);//设置共享内存大小为4096
if ( -1 == shmid )
{
if (EEXIST == errno)
{
shmid = shmget(key,4096,0666);
if (-1 == shmid)
{
perror("shmget 2");
return -1;
}
}
else
{
perror("shmget");
}
}
addr = shmat(shmid,NULL,0);//获得共享内存的空间地址
if ( (void*)(-1) == addr )
{
perror("shmat");
return -1;
}
while(1)
{
wait();//v操作,分配资源,使共享内存资源减1;使资源不可用
//--
printf("%s",addr);
}
ret = shmdt(addr);
if ( -1 == ret )
{
perror("shmdt");
return -1;
}
printf("%ld ",key);
return 0;
}
写端
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <errno.h>
#include <sys/sem.h>
#include <string.h>
#include <strings.h>
int semid = -1;
int fun_init(void)
{
int ret = -1;
key_t key = ftok("/home",2);//获得key值
if ( -1 == key )
{
perror("ftok");
return -1;
}
semid = semget(key,2,0666|IPC_CREAT|IPC_EXCL);//获得信号灯ID。包含2个信号灯
if ( -1 == semid )
{
if( EEXIST == errno )
{
semid = semget(key,2,0666);
if (-1 == semid )
{
perror("semget");
return -1;
}
}else
{
perror("semget");
return -1;
}
}
#if 1
ret = semctl(semid,0,SETVAL,0);//要修改的信号灯编号为0,SETVAL设置信号灯的值,值为0
if ( -1 == ret )
{
perror("semctl");
return -1;
}
#endif
return 0;
}
int post(void)
{
int ret = -1;
struct sembuf buf;
bzero(&buf,sizeof(struct sembuf));//将buf清零
buf.sem_num = 0;//要操作的信号灯编号为0
buf.sem_op = 1;//释放资源,V操作
buf.sem_flg = 0;//不知什么意思
ret = semop(semid,&buf,1);//要操作一个信号灯,信号灯编号为0,操作时释放资源,释放资源。使资源可用。解锁,使读端可以读
if ( -1 == ret )
{
perror("semop");
return -1;
}
}
int main(int argc,char **argv)
{
pid_t pid_r = -1;
int ret = -1;
int shmid = -1;
char *addr = NULL;
key_t key = ftok("/",1);//获得key值
if ( -1 == key )
{
perror("ftok");
return -1;
}
shmid = shmget(key,4096,0666|IPC_CREAT|IPC_EXCL);//共享内存的大小设为4096
if ( -1 == shmid )
{
if (EEXIST == errno)
{
shmid = shmget(key,4096,0666);
if (-1 == shmid)
{
perror("shmget 2");
return -1;
}
}
else
{
perror("shmget");
}
}
addr = shmat(shmid,NULL,0);//将共享内存映射到addr,0为共享内存可读可写
if ( (void*)(-1) == addr )
{
perror("shmat");
return -1;
}
ret = fun_init();//初始化信号灯,灯值为0
if ( -1 == ret )
{
perror("fun_init");
return -1;
}
//0
while(1)
{
fgets(addr,4096,stdin);//获得消息
//++
ret = post();//V操作,将值加1.释放资源,外部资源就加1;信号灯的值为1,资源可用
if( -1 == ret)
{
perror("post");
return -1;
}
}
ret = shmdt(addr);//删除共享内存映射后的地址
if ( -1 == ret )
{
perror("shmdt");
return -1;
}
printf("%ld ",key);
return 0;
}
#include <unistd.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <errno.h>
#include <sys/sem.h>
#include <string.h>
#include <strings.h>
int semid = -1;
int fun_init(void)
{
int ret = -1;
key_t key = ftok("/home",2);//获得key值
if ( -1 == key )
{
perror("ftok");
return -1;
}
semid = semget(key,2,0666|IPC_CREAT|IPC_EXCL);//获得信号灯ID。包含2个信号灯
if ( -1 == semid )
{
if( EEXIST == errno )
{
semid = semget(key,2,0666);
if (-1 == semid )
{
perror("semget");
return -1;
}
}else
{
perror("semget");
return -1;
}
}
#if 1
ret = semctl(semid,0,SETVAL,0);//要修改的信号灯编号为0,SETVAL设置信号灯的值,值为0
if ( -1 == ret )
{
perror("semctl");
return -1;
}
#endif
return 0;
}
int post(void)
{
int ret = -1;
struct sembuf buf;
bzero(&buf,sizeof(struct sembuf));//将buf清零
buf.sem_num = 0;//要操作的信号灯编号为0
buf.sem_op = 1;//释放资源,V操作
buf.sem_flg = 0;//不知什么意思
ret = semop(semid,&buf,1);//要操作一个信号灯,信号灯编号为0,操作时释放资源,释放资源。使资源可用。解锁,使读端可以读
if ( -1 == ret )
{
perror("semop");
return -1;
}
}
int main(int argc,char **argv)
{
pid_t pid_r = -1;
int ret = -1;
int shmid = -1;
char *addr = NULL;
key_t key = ftok("/",1);//获得key值
if ( -1 == key )
{
perror("ftok");
return -1;
}
shmid = shmget(key,4096,0666|IPC_CREAT|IPC_EXCL);//共享内存的大小设为4096
if ( -1 == shmid )
{
if (EEXIST == errno)
{
shmid = shmget(key,4096,0666);
if (-1 == shmid)
{
perror("shmget 2");
return -1;
}
}
else
{
perror("shmget");
}
}
addr = shmat(shmid,NULL,0);//将共享内存映射到addr,0为共享内存可读可写
if ( (void*)(-1) == addr )
{
perror("shmat");
return -1;
}
ret = fun_init();//初始化信号灯,灯值为0
if ( -1 == ret )
{
perror("fun_init");
return -1;
}
//0
while(1)
{
fgets(addr,4096,stdin);//获得消息
//++
ret = post();//V操作,将值加1.释放资源,外部资源就加1;信号灯的值为1,资源可用
if( -1 == ret)
{
perror("post");
return -1;
}
}
ret = shmdt(addr);//删除共享内存映射后的地址
if ( -1 == ret )
{
perror("shmdt");
return -1;
}
printf("%ld ",key);
return 0;
}