使用C/C++运行时库函数操作线程
Visual Studio包含了4个本机C/C++运行时库和2个用来管理MS.NET的C/C++运行时库。所有这些库都支持多线程编程环境:目前已经没有专门为单线程开发设计的C/C++运行时库了。表6-1对这些库进行了描述:
Libray Name
Description
LibCMt.lib
Statically linked release version of the library.
LibCMtD.lib
Statically linked debug version of the library.
MSVCRt.lib
Import library for dynamically linking the release version of the MSVCR80.dll library. (This is the default library when you create a new project.)
MSVCRtD.lib
Import library for dynamically linking the debug version of the MSVCR80D.dll library.
MSVCMRt.lib
Import library used for mixed managed/native code.
MSVCURt.lib
Import library compiled as 100-percent pure MSIL code.
当新建一个项目时,你应该知道当前项目链接的是哪一个库。在Visual Studio环境下,可以通过“项目属性”——“配置属性”——“C/C++”——“代码生成”——“运行时库”设置。
标准C运行时库是在1970年左右发布的,那时还没有线程这个概念,因此C运行时库的创造者们也没有意识到在多线程环境下使用C运行时库带来的问题。我们来举个例子,标准C运行时库中的全局变量errno用来表示最后一次函数调用的出错码,下面的代码段在多线程环境下可能会引发一些问题:
BOOL fFailure = (system("NOTEPAD.exe README.text") == -1);
if(fFailure){
switch(errno){
case E2BIG:
...
break;
case ENOENT:
...
break;
case ENOEXEC:
...
break;
case ENOMEM:
...
break;
}
}
假设当前线程在system调用后、if语句之前被中断,并且进程内的另外一个线程被调度且更改了errno的值,然后系统继续返回调度第一个线程,并判断errno,然而此时的errno已被另外的线程更改过,无法再准确的反应当system执行的状态了。为了解决这个问题,每个线程应该有自己的errno变量,此外应当保证每个线程只更改自己的errno而不会影响到其它线程。
这只是标准C/C++运行时库无法适应多线程环境的一个例子,事实上,在多线程环境下会出问题的C/C++运行时库变量和函数还包括(但不限于)_doserrno、strtok、_wcstok、strerror、
相关文档:
Delphi 与 C/C++ 数据类型对照表
Delphi数据类型C/C++
ShorInt
8位有符号整数
char
Byte
8位无符号整数
BYTE,unsigned short
SmallInt
16位有符号整数
short
Word
16位无符号整数
unsigned short
Integer,LongInt
32位有符号整数
int,long
Cardinal,LongWord/DWORD
32位无符号整数
unsigned long
Int6 ......
由于程序运行时占用的内存过大,所以想办法给程序瘦身。
在调试中发现结构体占用的size竟然和预想的不一样,原来……
看看下面讲的吧,肯定会不枉此看哦!
1,比如:
struct{
short a1;
short a2;
short a3;
}A;
struct{
long a1;
short a2;
}B;
sizeof(A)=6, sizeof(B)=8,为什么?
注:sizeof(sho ......
一家之言,欢迎拍砖哈。
1、可以考虑先学习C.
大多数时候,我们学习语言的目的,不是为了成为一个语言专家,而是希望成为一个解决问题的专家。做一个有用的程序员,做一个赚钱的程序员。我们的价值,将体现在客户价值上,而不是语言写得好不好看。
C++是C的一个面向对象的解释,C++为C扩充了大规模工程应 ......
int main(int argc,char *argv[])
argc(argument count):参数的个数;
argv(argument value):参数值
argv[0] :文件名
argv[1]:第一个参数,argv[2];第二个参数,以此类推。
编译C
1 单源程序到可执行程序
编译 & ......
我们已经了解如何定义线程入口点函数、调用系统API创建执行指定函数的线程。本节将揭示这一切在系统内部是如何完成的。
图6-1描述了线程创建并完成初始化后的状态。调用CreateThread会使系统产生一个线程内核对象,其引用计数(Usage count)被初始化为2(创建线程的进程和线程本身都引用了该内核对象),其它属性也完成了 ......