在是一个简易聊天中提到,一个进程只能做一件事,其实不然,只是当时没有涉及到线程的概念。所以今天在用多线程来实现一次。
依旧是两个程序,每个程序包含两个线程。
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <signal.h>
#include <pthread.h>
#include <unistd.h>
#define MSGKEY 1234 //键值
pthread_t tid[2] = {0};
struct msgbuf
{
long mtype;
char mtext[100];
};
/* 发送消息 */
void *Send(void *arg)
{
struct msgbuf buf;
int ret, oldtype;
pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, &oldtype);
while(1)
{
memset(&buf, 0, sizeof(buf)); //先清空缓冲区
scanf("%s", buf.mtext);
buf.mtype = 5; //消息类型(发)为5,可任意设置,但必须与后面一致
ret = msgsnd(*(int *)arg, &buf, sizeof(buf.mtext), 0);
if (-1 == ret) //发送失败
{
perror("msgsnd");
exit(1);
}
if (!strncmp(buf.mtext, "bye", 3)) //以bye结束
{
buf.mtype = 3; //消息类型
ret = msgsnd(*(int *)arg, &buf, sizeof(buf.mtext), 0);
if(-1 == ret)
{
perror("msgsnd");
exit(1);
}
break;
}
}
}
/* 接收消息 */
void *Receive(void *arg)
{
struct msgbuf buf;
int ret;
while(1)
{
memset(&buf, 0, sizeof(buf));
ret = msgrcv(*(int *)arg, &buf, sizeof(buf.mtext), 3, 0);
if (-1 == ret)
{
perror("msgrcv");
exit(1);
}
if (!strncmp(buf.mtext, "bye", 3))
{
pthread_cancel(tid[1]); //终止另一个线程
break;
}
printf("Receive : %s\n", buf.mtext);
}
}
int main()
{
int msgid;
int ret;
struct msgbuf buf; //注意buf是结构体
pid_t pid;
msgid = msgget(MSGKEY, IPC_CREAT | IPC_EXCL); //创建消息队列
if(-1 == msgid) //创建失败返回-1
{
perror("msgget");
exit(1);
}
ret = pthread_create(&tid[1], NULL, Send, (void *)&msgid); //创建线程
if (0 != ret)
{
perror("pthread_create1");
exit(1);
}
ret = pthread_create(&tid[0], NULL, Receive, (void *)&msgid);
if (0 != ret)
{
perror("pthread_create2");
exit(1);
}
pthread_join(tid[0], NULL); //线程等待
pthread_join(tid[1], NULL);
msgctl(msgid, IPC_RMID, NULL); //销毁消息队列
return 0;
}
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <signal.h>
#include <pthread.h>
#include <unistd.h>
#define MSGKEY 1234 //键值
pthread_t tid[2] = {0};
struct msgbuf
{
long mtype;
char mtext[100];
};
void *Send(void *arg)
{
struct msgbuf buf;
int ret, oldtype;
pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, &oldtype);
while(1)
{
memset(&buf, 0, sizeof(buf)); //先清空缓冲区
scanf("%s", buf.mtext);
buf.mtype = 3; //消息类型(发)为5,可任意设置,但必须与后面一致
ret = msgsnd(*(int *)arg, &buf, sizeof(buf.mtext), 0);
if (-1 == ret) //发送失败
{
perror("msgsnd");
exit(1);
}
if (!strncmp(buf.mtext, "bye", 3)) //以bye结束
{
buf.mtype = 5;
ret = msgsnd(*(int *)arg, &buf, sizeof(buf.mtext), 0);
if(-1 == ret)
{
perror("msgsnd");
exit(1);
}
if (!strncmp(buf.mtext, "bye", 3))
{
buf.mtype = 5;
ret = msgsnd(*(int *)arg, &buf, sizeof(buf.mtext), 0);
if(-1 == ret)
{
perror("msgsnd");
exit(1);
}
break;
}
}
}
}
void *Receive(void *arg)
{
struct msgbuf buf;
int ret;
while(1)
{
memset(&buf, 0, sizeof(buf));
ret = msgrcv(*(int *)arg, &buf, sizeof(buf.mtext), 5, 0);
if (-1 == ret)
{
perror("msgrcv");
exit(1);
}
if (!strncmp(buf.mtext, "bye", 3))
{
pthread_cancel(tid[1]);
break;
}
printf("Receive : %s\n", buf.mtext);
}
}
int main()
{
int msgid;
int ret;
struct msgbuf buf; //注意buf是结构体
pid_t pid;
msgid = msgget(MSGKEY, 0); //创建消息队列
if(-1 == msgid) //创建失败返回-1
{
perror("msgget");
exit(1);
}
ret = pthread_create(&tid[1], NULL, Send, (void *)&msgid);
if (0 != ret)
{
perror("pthread_create1");
exit(1);
}
ret = pthread_create(&tid[0], NULL, Receive, (void *)&msgid);
if (0 != ret)
{
perror("pthread_create2");
exit(1);
}
pthread_join(tid[0], NULL);
pthread_join(tid[1], NULL);
return 0;
}
个人感觉比使用进程来实现清爽很多,哈哈哈