由信号灯实现通信。
发送端send.c代码:
#include <myhead.h>
#include "./sem.h"
#define PAGE_SIZE 4096
int main(int argc, const char *argv[])
{
	int semid = semID_get(2);//创建2个信号灯
	key_t key = ftok("./",'U');
	if(key==-1)
	{
		perror("ftok");
		return -1;
	}
	int shmID = shmget(key,PAGE_SIZE,IPC_CREAT|0664);
	if(shmID==-1)
	{
		perror("shmget");
		return -1;
	}
	
	char *sendbuff = shmat(shmID,NULL,0);//映射出共享内存
	if(sendbuff==(void *)-1)
	{
		perror("shmat");
		return -1;
	}
	while(1)
	{
		P(semid,0);//申请0号灯资源
		printf("请输入你的信息:");
		fgets(sendbuff,PAGE_SIZE,stdin);
		sendbuff[strlen(sendbuff)-1]='\0';
		V(semid,1);//释放1号灯资源
		if(strcmp("quit",sendbuff)==0)
		{
			break;
		}
	}
	if(shmdt(sendbuff)==-1)
	{
		perror("shmat");
		return  -1;
	}
	if(shmctl(shmID,IPC_RMID,NULL)==-1)
	{
		perror("shmctl");
		return -1;
	}
	return 0;
}接收端rev.c代码:
#include <myhead.h>
#include "./sem.h"
#define PAGE_SIZE 4096
int main(int argc, const char *argv[])
{
	int semid = semID_get(2);
	key_t key = ftok("./",'U');
	if(key==-1)
	{
		perror("ftok");
		return -1;
	}
	int shmID = shmget(key,PAGE_SIZE,IPC_CREAT|0664);
	if(shmID==-1)
	{
		perror("shmget");
		return -1;
	}
	
	char *revbuff = shmat(shmID,NULL,0);//只读
	if(revbuff==(void *)-1)
	{
		perror("shmat");
		return -1;
	}
	while(1)
	{
		P(semid,1);//申请1号灯资源
		printf("%s\n",revbuff);
		if(strcmp("quit",revbuff)==0)
		{
			break;
		}
		V(semid,0);//释放0号灯
	}
	return 0;
}sem.c代码:
#include <myhead.h>
//初始化信号灯
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_semno(int SEMid,int SEMno)
{
	 union semun sem_INFO;
	printf("请输入编号为%d信号灯的值:",SEMno);
	scanf("%d",&sem_INFO.val);
	getchar();
	if(semctl(SEMid,SEMno,SETVAL,sem_INFO)==-1)
	{
		perror("semtal");
		return -1;
	}
	return 0;
}
//申请信号灯id,初始化信号灯,返回信号灯集的id
int semID_get(int SEMcount)
{
	key_t key = ftok("./",'Y');
	if(key==-1)
	{
		perror("key");
		return -1;
	}
	int SEMid;
	if((SEMid = semget(key,SEMcount,IPC_CREAT|IPC_EXCL|0664))==-1)
	{
		if(errno==EEXIST)
		{
			SEMid = semget(key,SEMcount,IPC_CREAT|0664);//已经存在直接打开即可
			return SEMid;
		}
		perror("semget");
		return -1;
	}
	int i;
	for(i = 0;i<SEMcount;i++)
	{
		init_semno(SEMid,i);//初始化信号灯
	}
	return SEMid;
}
int P(int SEMid,int SEMno)//申请资源
{
	
	struct sembuf SEM_op;
	SEM_op.sem_num = SEMno;//要申请资源的信号灯号
	SEM_op.sem_op = -1;//申请资源
	SEM_op.sem_flg = 0;//阻塞方式申请信号灯
	
	if(semop(SEMid,&SEM_op,1)==-1)//操作的灯个数
	{
		perror("semop P");
		return -1;
	}
	return 0;
}
int V(int SEMid,int SEMno)//释放资源
{
	
	struct sembuf SEM_op;
	SEM_op.sem_num = SEMno;//要申请资源的信号灯号
	SEM_op.sem_op = 1;//释放资源
	SEM_op.sem_flg = 0;//阻塞方式申请信号灯
	
	if(semop(SEMid,&SEM_op,1)==-1)//操作的灯个数
	{
		perror("semop V");
		return -1;
	}
	return 0;
}
int DEL_sem(int SEMid)
{
	if(semctl(SEMid,0,IPC_RMID)==-1)
	{
		perror("smectl");
		return -1;
	}
	return 0;
}
sem.h代码:
#ifndef _SEM_H_
#define _SEM_H_
//申请信号等集,返回信号灯集的id
int semID_get(int semno);//semno要设置灯的个数
//申请信号灯资源(value设置为0)
int P(int semID,int semno);//参数1:信号灯id,参数2灯的个数
//释放信号灯资源(value设置为1)
int V(int semID,int semno);
//删除信号灯集
int dele_sem(int semID);
#endif运行结果:









![[翻译+笔记] 用于视频生成的Diffusion Model](https://i-blog.csdnimg.cn/direct/a8ea90ff7e35446380cbf213c23437d1.png)










