需求:进程A对一个整数0执行1000000000次加操作
进程B对一个整数0执行1000000000次减操作
进程A,B并行执行,最后的数据结果应该是0
注意要先执行A,初始化信号量。
进程A:
#include<sys/types.h>
#include<sys/ipc.h>
#include<sys/stat.h>
#include<sys/shm.h>
#include<sys/sem.h>
#include<fcntl.h>
#include<stdlib.h>
#include<time.h>
#include<stdio.h>
#include<string.h>
#define SHM_KEY 2222
#define SEM_KEY 5555
void P(int semid)
{
// 第一个元素-1值代表信号量值减一,当信号量值小于等于0的值的时候等待
struct sembuf sem1_opt_wait[3]={0,-1,0};
// semop(semid,sembuf,1) 将sembuf的第二个元素-1加到semid上,当信号量值为负数的值的时候等待
if(semop(semid, sem1_opt_wait, 1)==-1)
{
perror("semop");
exit(EXIT_FAILURE);
}
return;
}
int V(int semid)
{
// 第一个元素-1值代表信号量值减一,当信号量值小于等于0的值的时候等待
struct sembuf sem1_opt_release[3]={0,1,0};
// semop(semid,sembuf,1) 将sembuf的第二个元素-1加到semid上,当信号量值为负数的值的时候等待
if(semop(semid, sem1_opt_release, 1)==-1)
{
perror("semop");
exit(EXIT_FAILURE);
}
return;
}
union semun
{
int setval;
struct semid_ds *buf;
unsigned short *array;
};
int main()
{
int shmid,semid;
int *addr;
int h=0,w=0;
// 设置初始信号量的值为1
union semun sem_args;
unsigned short array[1]={1};
sem_args.array = array;
shmid = shmget((key_t)SHM_KEY,getpagesize(),0666| IPC_CREAT);
if(shmid==-1)
{
perror("shmget error:");
exit(EXIT_FAILURE);
}
semid = semget((key_t)SEM_KEY,2, 0666| IPC_CREAT);
if(semid==-1)
{
perror("semget error:");
exit(EXIT_FAILURE);
}
int ret = semctl(semid,1,SETALL,sem_args);
if(ret == -1)
{
perror("shmctl error:");
exit(EXIT_FAILURE);
}
P(semid);
addr=shmat(shmid,0,0);
*addr = 0;
int i = 0;
for(; i < 1000000000; i++)
{
(*addr)++;
}
V(semid);
return 0;
}
进程B:
#include<sys/types.h>
#include<sys/shm.h>
#include<sys/sem.h>
#include<string.h>
#include<stdio.h>
#include<stdlib.h>
#include<sys/stat.h>
#define SHM_KEY 2222
#define SEM_KEY 5555
void P(int semid)
{
// 第一个元素-1值代表信号量值减一,当信号量值为负数的值的时候等待
struct sembuf sem1_opt_wait[1]={0,-1,0};
// semop(semid,sembuf,1) 将sembuf的第二个元素-1加到semid上,当信号量值为负数的值的时候等待
if(semop(semid, sem1_opt_wait, 1)==-1)
{
perror("semop");
exit(EXIT_FAILURE);
}
return;
}
int V(int semid)
{
// 第一个元素-1值代表信号量值减一,当信号量值为负数的值的时候等待
struct sembuf sem1_opt_release[1]={0,1,0};
// semop(semid,sembuf,1) 将sembuf的第二个元素-1加到semid上,当信号量值为负数的值的时候等待
if(semop(semid, sem1_opt_release, 1)==-1)
{
perror("semop");
exit(EXIT_FAILURE);
}
return;
}
int main()
{
int shmid,semid;
int *addr;
shmid=shmget((key_t)SHM_KEY,sizeof(int*), S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH);
if(shmid==-1)
{
perror("shmget error:");
exit(EXIT_FAILURE);
}
semid = semget((key_t)SEM_KEY,2,0600);
if(semid==-1)
{
perror("semget error:");
exit(EXIT_FAILURE);
}
addr = shmat(shmid,0,0);
P(semid);
printf("before:%d\n", *addr);
int i = 0;
for(; i < 1000000000; i++)
{
(*addr)--;
}
V(semid);
printf("after:%d\n", *addr);
shmdt(addr);
shmctl(shmid,IPC_RMID,0);
semctl(semid,IPC_RMID,0);
}
gcc shared_write.c -o shared_write
gcc shared_write2.c -o shared_write2
./shared_write
./shared_write2
执行结果: