程序的实现是两个进程,通过信号量来实现通信,发送方先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; }