消息队列和信号量

程序的实现是两个进程,通过信号量来实现通信,发送方先request发送方的信号量,然后发送,然后再release接收方信号量,这样可以通知接手方可以接收了,接受方接收以后再通过信号量通知发送方,一直这样循环,直到发送方发送"exit"双方才能退出进程。

数据的传送是通过消息队列传送的。

具体对函数的介绍和实现方法这里就不多说了,信号量和消息队列的知识点还是有点多的,可以参考《linux程序设计》这本书,书上讲的很详细,例题也很好!

下面就贴上代码给大家参考参考!

发送代码:

#include <stdio.h>
#include <sys/ipc.h>
#include <sys/types.h>
#include <sys/sem.h>
#include <sys/msg.h>
#include <unistd.h>
#include <stdlib.h>
#define SIZE 128

struct msgbuf//消息的发送和接受要用到的结构体
{
	long mtype;//消息的类型
	char mtext[SIZE];//消息的数据
};

/*
*功能:发送消息
*参数1:信号量的ID
*参数2:消息的ID
*如果发送“exit”字符串,返回-1,其它返回0;
*/
int send(int sem_id, int msg_id)
{
	struct msgbuf msg;
	if ( request_sem(sem_id, 0) == -1 )//请求第一个信号量的资源
	{
		printf("request the frist semaphore failed!\n");
	}
	msg.mtype = 1;
	printf("input:");
	fgets(msg.mtext,sizeof(msg.mtext),stdin);
	msgsnd(msg_id, &msg, SIZE, 0);//发送到消息队列中

	if ( release_sem(sem_id,1) == -1 )//释放第二个信号量的资源
	{
		printf("release the second semaphore failed!\n");
	}
	if ( strcmp(msg.mtext,"exit\n") == 0 )
		return -1;
	return 0;
}

void init_sem(int sem_id)
{
	semctl(sem_id,0,SETVAL,1);//对第一个信号量的初始化
	semctl(sem_id,1,SETVAL,0);//对第二个信号量的初始化
}

int create_sem(key_t key)//创建信号量
{

	return semget(key,2,IPC_CREAT | 0666 );
}

int create_msg(key_t key)//创建消息队列
{

	return msgget(key,IPC_CREAT | 0666);
}

int release_sem(int sem_id, int i)//释放信号量函数
{
	struct sembuf sb;
	sb.sem_num = i;//信号量的索引
	sb.sem_op = 1;//1表示信号量加1
	sb.sem_flg = SEM_UNDO;//信号量资源不够时等待资源的释放
	return semop(sem_id,&sb,1);	
}

int request_sem(int sem_id, int i)//信号量的请求
{
	struct sembuf sb;
	sb.sem_num = i;
	sb.sem_op = -1;//-1表示信号量-1
	sb.sem_flg = SEM_UNDO;
	return semop(sem_id,&sb,1);
}

int main()
{
	int sem_id;
	int msg_id;
	key_t key;
//	char buffer[SIZE];
	key = ftok(".",'e');
	sem_id = create_sem(key);
	msg_id = create_msg(key);
	if (sem_id == -1 || msg_id == -1)
	{
		printf("create failed\n");
		exit(0);
	}
	init_sem(sem_id);
	while(1)
	{
		if ( send(sem_id, msg_id) == -1 )
			break;	
	}
			
	return 0;
}

第二段代码就不注释了,大致相同,如果第一段能看懂第二段就没问题了。

接收代码:


#include <stdio.h>
#include <sys/ipc.h>
#include <sys/types.h>
#include <sys/sem.h>
#include <sys/msg.h>
#include <unistd.h>
#include <stdlib.h>
#define SIZE 128

struct msgbuf
{
	long mtype;
	char mtext[SIZE];
};


int recive(int sem_id, int msg_id)
{
	struct msgbuf msg;
	if ( request_sem(sem_id, 1) == -1 )
	{
		printf("request the second semaphore failed!\n");
	}
	msgrcv(msg_id, &msg, SIZE, 0, 0);
	printf("%s",msg.mtext);
	if ( strcmp(msg.mtext,"exit\n") == 0)
		return -1;
	if ( release_sem(sem_id,0) == -1 )
	{
		printf("release the frist semaphore failed!\n");
	}
	return 0;
}


void init_sem(int sem_id)
{
	semctl(sem_id,0,SETVAL,1);
	semctl(sem_id,1,SETVAL,0);
}

int create_sem(key_t key)
{

	return semget(key,2,IPC_CREAT | 0666 );
}

int create_msg(key_t key)
{

	return msgget(key,IPC_CREAT | 0666);
}

int release_sem(int sem_id, int i)
{
	struct sembuf sb;
	sb.sem_num = i;
	sb.sem_op = 1;
	sb.sem_flg = SEM_UNDO;
	return semop(sem_id,&sb,1);	
}

int request_sem(int sem_id, int i)
{
	struct sembuf sb;
	sb.sem_num = i;
	sb.sem_op = -1;
	sb.sem_flg = SEM_UNDO;
	return semop(sem_id,&sb,1);
}

int main()
{
	int sem_id;
	int msg_id;
	key_t key;
	key = ftok(".",'e');
	sem_id = create_sem(key);
	msg_id = create_msg(key);
	if (sem_id == -1 || msg_id == -1)
	{
		printf("create failed\n");
		exit(0);
	}
	while(1)
	{
		if ( recive(sem_id, msg_id) == -1)
			break;	
	}		
	msgctl(msg_id,IPC_RMID,0);
	return 0;
}


你可能感兴趣的:(消息队列和信号量)