您的位置:首页 > 运维架构 > Linux

基于Linux C的聊天室客户端(三)多线程

2014-06-02 13:50 211 查看
上次说到如何去解决解析xml格式响应的问题,这次就来说一下多线程。这个聊天室需要多线程是很显然的,用户需要不断去输入指令或者是发送信息,这是一个线程,但是后台肯定还需要另一个线程去不断获取聊天室是否有新的聊天内容,要是没有就不输出新的,要是有就获取过来输出。

虽然这个聊天室的传输协议本来就设计成是获取消息和发送消息用的是同样的方法,但是如果不用多线程,那就只能在用户发消息过去的时候才会得到新消息,这也太怪了...所以还是要用。

那Linux C要用多线程就要使用到Pthreads(POSIX threads)

首先肯定是

#include <pthread.h>
然后在编译的时候要加上 -l pthread 否则没法编译,原因和上次说的libxml2一样。
下面就可以具体说这个pthread的使用了:

这次使用这个只用到了基本中的基本,什么互斥锁之类的都没用上,因为不需要,所以这个实例非常的简易,先是创建线程,使用 pthread_create 函数,函数原型是:

int pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine) (void *), void *arg);
这个函数的返回值就能代表是否创建成功,如果成功就应该返回 0 。

下面说一下传递进去的参数,第一个是指向 pthread_t 类型的对象的指针,这个类型的定义是:

typedef unsigned long int pthread_t;
也就是一个 unsigned long int 而已,这个用来代表线程的 id 。

第二个参数是属性,这次没有特别需要,所以笔者就给了个 NULL 。

第三个参数是函数指针,这个是一定要传进去的,这个指针指向的函数就是线程将要去执行的函数,注意这里的类型,所以如果返回值不一样的话是要进行强制类型转换的。

第四个参数就是第三个参数指向的函数的参数表,由于这次用不上,所以笔者也给了个 NULL 进去。

写起来是这样的:

int retThreadMain, retThreadMessage, tmp;
pthread_t mainThread, messageThread;
retThreadMain = pthread_create(&mainThread, NULL, (void * )&mainLoop, NULL);
retThreadMessage = pthread_create(&messageThread, NULL, (void *)&messageLoop, NULL);
if(retThreadMain!=0){
printf("fail to create main thread!\n");
return;
}
if(retThreadMessage!=0){
printf("fail to create message thread!\n");
return;
}
判断好线程创建成功后就要去调用一个 pthread_join 函数,这个函数的目的是使得主线程能够等待子线程的结束之后才结束,防止主线程过快结束以至于子线程没有时间执行,函数原型:

int pthread_join(pthread_t thread, void **retval);
第一个参数显然是线程的 id ,第二是用来记录返回值的,但是这次没用上,所以依然传递 NULL ,写出来是这样的:

tmp = pthread_join(mainThread, NULL);
if(tmp!=0){
printf("fail to join main thread!\n");
}
tmp = pthread_join(messageThread, NULL);
if(tmp!=0){
printf("fail to join message thread!\n");
}
依然是成功返回 0 。

下面贴一下两个线程里面跑的函数:

第一个是mainLoop,这个函数是用来接收用户发的指令,如果用户发的指令是以‘-’开头,那么就会调用 order 处理函数去处理这个指令,如果是其他情况,那么就认为用户是在往聊天室里发消息,就调用 message 发送函数去发送这条消息:

int mainLoop(){
// 输入字符串
char str[BUFSIZ];
// 状态码
int statusCode;
strcpy(_username, "");
strcpy(_time, "1980.01.01/00:00:00");
printf("this is a simple chat room\n");
printf("(please input -h for more help)\n");
while(1){
scanf("%s", str);
if(str[0]=='-')
order(str);
else
statusCode = sendMessage(str);
//接下来最好对statusCode 做一下判断
}
}
第二个是messageLoop,如前文所述,这个是为了能不断获取聊天室的聊天情况,然后会不断循环发空 message 到服务器来获取新消息,里面有两个函数,一个 start 一个 stop ,用来控制这个函数是否向服务器发请求,也就是说,即便 stop,这个线程也还在运行,只不过不去发请求了而已,等到 start 函数再次被调用,这个函数又会继续发请求:

#define	SLEEP_TIME	1
static int shouldRun = FALSE;
/**
* 停止线程
*/
void stopMessageThread(){
shouldRun = FALSE;
}

/**
* 开始线程
*/
void startMessageThread(){
shouldRun = TRUE;
}

/**
* 循环获取消息
*/
void messageLoop(){
int returnCode;
while(TRUE){
sleep(SLEEP_TIME);
if(shouldRun){
returnCode = sendMessage("");
if(returnCode == 400||returnCode == 404){
stopMessageThread();
}
}
}
}


如果是要学习pthread怎么用,这个例子并不好,因为涉及的东西太少,所以如果是想深入了解,还是要找找别的教程看看 =_=||

----------------------------------------------------------------------

然后就没有然后了...下次再说
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: