让2个终端之间互相聊天,使用消息队列去实现
#include <myhead.h>
//使用消息队列实现两个进程的相互聊天
#define ERR_MSG(msg) do{fprintf(stderr,"__%d__",__LINE__);\
perror(msg);\
}while(0)
int msgid;
typedef struct{
long mtype;
char text[256];
}msg_t;
void *rtask(void *arg){
msg_t buf;
long rtype=*((long *)arg);
while(1){
memset(buf.text,0,sizeof(buf.text));
if(msgrcv(msgid,&buf,sizeof(buf.text),rtype,0)<0){
ERR_MSG("msgrcv");
break;
}
if(0==strcmp(buf.text,"quit")){
printf("user2 offline\n");
break;
}
printf("\033[8Duser2:%s\n",buf.text);
printf("请输入:");
fflush(stdout);
}
pthread_exit(NULL);
}
void *wtask(void *arg){
msg_t buf;
long wtype=*((long *)arg);
buf.mtype=wtype;
while(1){
memset(buf.text,0,sizeof(buf.text));
printf("请输入:");
fgets(buf.text,sizeof(buf.text),stdin);
buf.text[strlen(buf.text)-1]='\0';
if(msgsnd(msgid,&buf,sizeof(buf.text),0)<0){
ERR_MSG("msgsnd");
break;
}
if(0==strcmp(buf.text,"quit")){
printf("user1 offline\n");
break;
}
}
pthread_exit(NULL);
}
int main(int argc, const char *argv[])
{
//创建秘钥
key_t key=ftok("/",19);
if(key<0){
ERR_MSG("ftok");
return -1;
}
//创建消息队列
msgid=msgget(key,IPC_CREAT|0664);
if(msgid<0){
ERR_MSG("msgget");
return -1;
}
long rtype=1;
long wtype=2;
pthread_t rtid,wtid;
if(pthread_create(&rtid,NULL,rtask,&rtype)!=0){
ERR_MSG("rtask");
return -1;
}
if(pthread_create(&wtid,NULL,wtask,&wtype)!=0){
ERR_MSG("wtask");
return -1;
}
pthread_join(rtid,NULL);
pthread_join(wtid,NULL);
//删除消息队列
msgctl(msgid,IPC_RMID,0);
return 0;
}
让2个终端之间互相聊天使用共享内存 + 信号灯集去实现
#include <myhead.h>
//使用共享内存和信号灯集实现两个进程聊天
#define ERR_MSG(msg) do{fprintf(stderr,"__%d__",__LINE__);\
perror(msg);\
}while(0)
typedef struct{
char buf[256];
}shm_t;
void semwait(int semid,int sem_num){
struct sembuf buf;
buf.sem_num=sem_num;
buf.sem_op=-1;
buf.sem_flg=SEM_UNDO;
semop(semid,&buf,1);
}
void sempost(int semid,int sem_num){
struct sembuf buf;
buf.sem_num=sem_num;
buf.sem_op=1;
buf.sem_flg=SEM_UNDO;
semop(semid,&buf,1);
}
shm_t *addr;
int semid;
int shmid;
void sighandler(int signal){
if(SIGCHLD==signal){
while(waitpid(-1,NULL,0)>0);
//删除共享内存的映射
shmdt(addr);
//删除共享内存
shmctl(shmid,IPC_RMID,0);
//删除信号灯集
semctl(semid,0,IPC_RMID,0);
exit(0);
}
}
int main(int argc, const char *argv[])
{
//创建秘钥
key_t key=ftok("/",7);
if(key<0){
ERR_MSG("ftok");
return -1;
}
//创建共享内存
shmid=shmget(key,sizeof(shm_t),IPC_CREAT|0664);
if(shmid<0){
ERR_MSG("shmget");
return -1;
}
//将共享内存映射到进程的内存空间
addr=shmat(shmid,NULL,0);
if(addr==(void*)-1){
ERR_MSG("shmat");
return -1;
}
//创建信号灯集
semid=semget(key,4,IPC_CREAT|0664);
if(semid<0){
ERR_MSG("semget");
return -1;
}
//初始化信号灯集
if(semctl(semid,0,SETVAL,1)<0){
ERR_MSG("semctl");
return -1;
}
if(semctl(semid,2,SETVAL,0)<0){
ERR_MSG("semctl");
return -1;
}
pid_t pid=fork();
if(pid>0){
//user1发送
while(1){
signal(SIGCHLD,sighandler);
semwait(semid,0);
memset(addr->buf,0,sizeof(addr->buf));
printf("请输入:");
fgets(addr->buf,sizeof(addr->buf),stdin);
addr->buf[strlen(addr->buf)-1]='\0';
sempost(semid,2);
if(0==strcmp(addr->buf,"quit")){
printf("user1 offline\n");
break;
}
}
exit(0);
}
else if(0==pid){
//user1接收
while(1){
semwait(semid,3);
if(0==strcmp(addr->buf,"quit")){
printf("user2 offline\n");
break;
}
printf("\033[8Duesr2:%s\n",addr->buf);
printf("请输入:");
fflush(stdout);
memset(addr->buf,0,sizeof(addr->buf));
sempost(semid,1);
}
exit(0);
}
else{
ERR_MSG("fork");
return -1;
}
return 0;
}