程序的实现是两个进程,通过信号量来实现通信,发送方先request发送方的信号量,然后发送,然后再release接收方信号量,这样可以通知接手方可以接收了,接受方接收以后再通过信号量通知发送方,一直这样循环,直到发送方发送"exit"双方才能退出进程。
数据的传送是通过消息队列传送的。
具体对函数的介绍和实现方法这里就不多说了,信号量和消息队列的知识点还是有点多的,可以参考《linux程序设计》这本书,书上讲的很详细,例题也很好!
下面就贴上代码给大家参考参考!
发送代码:
#include
#include
#include
#include
#include
#include
#include
#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
#include
#include
#include
#include
#include
#include
#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;
}