简单的多线程(活用OD解决运行时错误)

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了简单的多线程(活用OD解决运行时错误)相关的知识,希望对你有一定的参考价值。

代码源自《VC++深入详解》第15章 “多线程”,位于第563页 - 566 页。

程序的目的是展示多线程运行的效果:

#include <windows.h>
#include <iostream.h>

DWORD WINAPI Fun1Proc(
  LPVOID lpParameter   // thread data
);

int index = 0;

int main()
{
    HANDLE hThread1;
    hThread1 = CreateThread( NULL,0,Fun1Proc,NULL,0,NULL );
    CloseHandle( hThread1 );
    while ( index++ < 1000 )
        cout << "main thread is running." << endl;

    return 0;
}

DWORD WINAPI Fun1Proc(
  LPVOID lpParameter   // thread data
)
{
    while ( index++ < 1000 )
        cout << "thread1 is running" << endl;

    return 0;
}
 

运行时却发现程序崩溃了:

技术分享

单击取消用OD调试:

技术分享

发现程序是因为读一个0地址的内存引发了异常。在VC6中F5调试程序:

技术分享

技术分享

黄箭头指向的代码中对指针p解引用,而p的的值为0,这引发了异常。右击打开文件的属性,查看文件名:

技术分享

是一个C语言文件,文件名为WRITE,写入的意思。我们的程序什么操作用到了写入呢?没错!用到了cout向屏幕输出字符串。

将#include 语句改为标准格式:

#include <windows.h>
#include <iostream>

using namespace std;

DWORD WINAPI Fun1Proc(
  LPVOID lpParameter   // thread data
);

int index = 0;

int main()
{
    HANDLE hThread1;
    hThread1 = CreateThread( NULL,0,Fun1Proc,NULL,0,NULL );
    CloseHandle( hThread1 );
    while ( index++ < 1000 )
        cout << "main thread is running." << endl;

    return 0;
}

DWORD WINAPI Fun1Proc(
  LPVOID lpParameter   // thread data
)
{
    while ( index++ < 1000 )
        cout << "thread1 is running" << endl;

    return 0;
}

就可以完美运行:

技术分享

然而,这是为什么呢?我们只是猜到出问题的地址,并不了解其中的原理。尝试着百度一下:

iostream.h与iostream是不同的。
#include<iostream.h>是在旧的标准C++中使用。在新标准中,用#include<iostream>。iostream的意思是输入输出流。#include<iostream>是标准的C++头文件,任何符合标准的C++开发环境都有这个头文件。还要注意的是:在VC编程时要添加:
using namespace std;
其原因是:后缀为.h的头文件C++标准已经明确提出不支持了,早些的实现将标准库功能定义在全局空间里,声明在带.h后缀的头文件里,C++标准为了和C区别开,也为了正确使用命名空间,规定头文件不使用后缀.h。因此,当使用<iostream.h>时,相当于在C中调用库函数,使用的是全局命名空间,也就是早期的C++实现;当使用<iostream>的时候,该头文件没有定义全局命名空间,必须使用namespace std;这样才能正确使用cout。

关系

<string.h>是旧的C头文件,对应的是基于char*的字符串处理函数;<string>是包装了std的C++头文件,对应的是新的string类;<cstring>是对应旧的C头文件的std版本。而<iostream.h>和<iostream>的关系,类似于<string.h>和<cstring>的关系,实现的功能是相同的,主要是是否使用命名空间std的区别。
原因就是我们使用了C++标准不支持的.h头文件,而其中的处理函数则是C语言编写的,这样基于char*的处理函数在多线程时很可能出现大问题,还是用<iostream>比较安全,也比较符合标准。

以上是关于简单的多线程(活用OD解决运行时错误)的主要内容,如果未能解决你的问题,请参考以下文章

多线程编程 - PHP 实现

多线程编程 - PHP 实现

多线程

带继承的多线程 (C++)

如何解决数组上的多线程问题

Python的多线程threading和多进程multiprocessing