linux下C语言编程7-信号量与共享内存

当我们使用共享内存时,必然要面对一个问题:并发。信号量可以控制共享资源的申请和释放,起到锁的目的,有效的解决了并发带来的种种问题。

共享内存的使用见《linux下C语言编程4-使用共享内存实现进程间通信2》

信号量的函数见《linux下C语言编程6-信号量函数semget() semop() semctl() 》

下面给出一个例子:

服务端:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

#include <sys/sem.h>
#include <sys/ipc.h>
#define SEGSIZE 1024


// 生成信号量
int sem_create(key_t key)
{
	int semid;

	semid = semget(key, 250, IPC_CREAT|0666);
	if (semid == -1)
	{
		printf("create semaphore error/n");
		exit(0);
	}
	semctl(semid,0,SETVAL);
	return semid;
}
//删除信号量
void del_sem(int semid)
{
	semctl(semid,0,IPC_RMID);
}
//p
int p(int semid) {
/*
sembuf第2个参数sem_op:
如果其值为正数,该值会加到现有的信号内含值中。通常用于释放所控资源的使用权;
如果sem_op的值为负数,而其绝对值又大于信号的现值,操作将会阻塞,直到信号值大于或等于sem_op的绝对值。通常用于获取资源的使用权;
如果sem_op的值为0,则操作将暂时阻塞,直到信号的值变为0。
*/
  struct sembuf sops = {1,-1,SEM_UNDO};	// sops数组大小为1
  return semop(semid,&sops,1);
}
//v
int v(int semid) {
  struct sembuf sops = {1,+1,SEM_UNDO};
return semop(semid,&sops,1);
}
int main()
{
	key_t key;
	int shmid,semid;
	char *shm;
	char msg[32] = "xiaoshe-";
	char i;
	struct semid_ds buf;
	key = ftok("/",0);
	
	shmid = shmget(key,SEGSIZE,IPC_CREAT|0604);
	if (-1 == shmid){
		printf(" create shared memory error/n");
		return -1;
	}
	printf("shmid = %d/n", shmid);
	
	shm = (char *)shmat(shmid, 0, 0);
	if (-1 == (int)shm){
		printf(" attach shared memory error/n");
		return -1;
	}
	
	semid = sem_create(key);
	printf("semid = %d/n", semid);
	for (i=0; i<3; i++)
	{
		sleep(2);
		p(semid);
		printf("[%d] p ", i);fflush(stdout);
		
		sleep(1);
		// 修改共享内存
		
		msg[8] = '0' + i;
		memcpy(shm, msg, 32);
		printf("-> wirte ");fflush(stdout);
		
		sleep(3);
		v(semid);
		printf("-> v/n");
	}
	shmdt(shm);
	shmctl(shmid,IPC_RMID,&buf);
	del_sem(semid);
	
	return 0;
//gcc -o s s.c -g
}

客户端:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sys/sem.h>
#include <time.h>
#include <sys/ipc.h>
#define SEGSIZE 1024



//创建信号量
int get_sem(key_t key)
{
	int semid;
	semid = semget(key,20,0);
	if (-1 == semid){
		printf("create semaphore error/n");
		exit(1);
	}
	return semid;
}
//等待信号量变成0
void wait_v(int semid)
{
	struct sembuf sops={1,0,0};
	semop(semid,&sops,1);
}
int main(void)
{
	key_t key;
	int shmid, semid;
	char *shm;
	char msg[100];
	char i;
	key = ftok("/",0);
	shmid = shmget(key,SEGSIZE,0);
	if(-1 == shmid)
	{
		printf(" create shared memory error/n");
		return -1;
	}
	
	shm = (char *)shmat(shmid,0,0);
	if (-1 == (int)shm){
		printf(" attach shared memory error/n");
		return -1;
	}
	
	semid = get_sem(key);
	printf("semid = %d/n", semid);
	for (i=0; i<4; i++)
	{
		sleep(1);
		wait_v(semid);
		printf("[%d] msg = '%s'/n", i, shm);
	}
	shmdt(shm);
	return 0;
// gcc -o c c.c 





}

  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值