C++:多线程类库的设计与实现(二)
来源:互联网 发布:亚伟晓军判卷软件下载 编辑:程序博客网 时间:2024/05/16 12:31
历史回顾---C时代的多线程设计
上一篇文章中说明了我们的线程类的设计目标是简单、实用和方便移植,然后说明了我们在Linux和Windows上的开发环境。为简单起见,在后续内容中我们将使用Linux作为主要开发平台,以g++(gcc)3.4.4为开发环境。
我们首先来回顾一下在C中是怎样设计多线程程序的。
假设我们要设计一个程序,它包含两个线程。主线程用于响应用户命令,当用户在标准输入上键入”quit”并按下回车后就结束程序,另外一个线程则每隔3秒钟在标准输出上打印一行”I am alive”消息。
这样的程序应该是下面这个样子。
// File : thread1.c
#include <stdio.h>
#include <unistd.h>
extern volatile int g_iQuitFlag;
void *thread1_function(void *arg) {
while(g_iQuitFlag != 1) {
printf("I am alive.\n");
sleep(3);
}
return NULL;
}
//--EOF--
// File : main.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <pthread.h>
volatile int g_iQuitFlag;
extern void *thread1_function(void *arg);
int main()
{
char szBuf[1024];
int iRes;
pthread_t t1;
iRes = pthread_create(&t1, NULL, thread1_function, NULL);
if (iRes != 0) {
perror("Calling pthread_create failed.");
exit(-1);
}
while(1) {
fgets(szBuf, sizeof(szBuf), stdin);
if(0 == strncmp(szBuf, "quit", 4)) {
g_iQuitFlag = 1;
break;
}
}
pthread_join(t1, NULL);
return 0;
}
//--EOF--
两个文件应该被放到同一个目录下,编译命令为:
g++ main.c thread1.c -lpthread
环境配置没有问题的话,编译器(以及被自动调用的链接器)将产生一个名为a.out的文件。执行该文件:
xxxx$ ./a.out
到目前为止,一切看起来都很顺利。我们为子线程编写一个例程函数,然后在主线程创建子线程。主线程中通过改变全局变量的值来通知子线程结束自己。主线程在设置该全局变量后等待子线程结束后退出,程序结束。
上面的例子中有一个小问题,就是用户在输入“quit”后程序不是立即退出的,需要等一小会。这是因为子线程每隔3秒钟检查一次退出标志,在下一个3秒钟到来之前子线程是没有响应的。我们在稍后的文章中将介绍一个更好的办法来解决这个问题。
这个程序的Windows版本如下。
// File : thread1.c
#include <Windows.h>
#include <stdio.h>
extern volatile int g_iQuitFlag;
DWORD WINAPI thread1_function(LPVOID arg) {
while(g_iQuitFlag != 1) {
printf("I am alive.\n");
Sleep(3 * 1000);
}
return 0;
}
//--EOF--
// File : main.c
#include <Windows.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
volatile int g_iQuitFlag;
extern DWORD WINAPI thread1_function(LPVOID arg);
int main()
{
char szBuf[1024];
HANDLE t1;
t1 = CreateThread(NULL,
0,
thread1_function,
NULL,
0,
NULL);
if (t1 == NULL) {
perror("Calling pthread_create failed.");
exit(-1);
}
while(1) {
fgets(szBuf, sizeof(szBuf), stdin);
if(0 == strncmp(szBuf, "quit", 4)) {
g_iQuitFlag = 1;
break;
}
}
WaitForSingleObject(t1, INFINITE);
CloseHandle(t1);
return 0;
}
//--EOF--
注意到Windows的Sleep单位是毫秒,而Linux的sleep单位是秒。另外Windows的线程句柄需要在线程结束后被关闭。
我们可以使用IDE建立一个程序项目来编译程序,也可以使用命令行来编译。命令行的编译指令为:
cl main.c thread1.c /MT
注意VC++的多线程库开关MT。使用IDE的场合也需要打开多线程库支持开关。
- C++:多线程类库的设计与实现(二)
- C++:多线程类库的设计与实现(一)
- C++:多线程类库的设计与实现(三)
- C++:多线程类库的设计与实现(四)
- C++:多线程类库的设计与实现(五)
- C++:多线程类库的设计与实现(六)
- C++:多线程类库的设计与实现(七)
- 《Redis设计与实现》[第二部分]单机数据库的实现-C源码阅读(二)
- C++多线程类库的设计与实现(八)完
- EF6的多线程与分库架构设计实现
- EF6的多线程与分库架构设计实现
- EF6的多线程与分库架构设计实现
- EF6的多线程与分库架构设计实现
- EF6的多线程与分库架构设计实现
- ftp 多线程下载的设计与实现
- ftp 多线程下载的设计与实现
- C语言栈的实现--学习组合设计(二)
- 有限状态机(FSM)的设计与实现(二)
- Glib库的安装和编译
- android 自动接听原码
- How to Generate Hibernate Pojo Classes from DB Tables
- hibernate 一对多双向关联在多方重写equals和hashCode方法
- mysql 性能调优3--监控工具
- C++:多线程类库的设计与实现(二)
- 瓦片服务: 地图切片链接
- C++:多线程类库的设计与实现(三)
- 一个十分有用的标准C++写的split(string) 函数
- Android利用canvas画各种图形(点、直线、弧、圆、椭圆、文字、矩形、多边形、曲线、圆角矩形)
- 小人物的互联网创业心经 先要赚钱活下来
- C++:多线程类库的设计与实现(四)
- RadioButtonList 选项的水平排列 自动换行
- Jboss .netty项目使用的netty包详解之 org.jboss.netty.handler.codec.base64