简单的多线程(活用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>比较安全,也比较符合标准。

时间: 2024-08-04 16:24:19

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

简单的多线程买票模拟程序(lock解决多线程存在大安全隐患)

—————————————————————— jdk1.5的lock代替synchronized,condition封装 Object对象里sleep,wait,notify ,notifyAll —————————————————————— /*  需求:  写一个简单的多线程模拟买票的程序  四个买票窗口,一共有100张票 */import java.util.concurrent.locks.*;   class Tick implements Runnable{         priv

简单的多线程并发同步演示

#include "stdafx.h"#include <iostream>#include <Windows.h>using namespace std;HANDLE hMutex;DWORD WINAPI Fun(LPVOID lp){    while(1){        WaitForSingleObject(hMutex,INFINITE);        cout<<"fun"<<endl;//如果不用信

MAC COCOA一个简单的多线程程序

功能: 实现多线程:2个线程同时工作,一个用时间计数器,一个用来打印信息 STEP1 XCODE ->New Application ->Cocoa中的Command Line 自动增加: #include <CoreFoundation/CoreFoundation.h> STEP2 // // main.c // test_runloop1 // // Created by DMD on 20/6/14. // Copyright (c) 2014 EDU. All right

简单的多线程买票模拟程序

/*  需求:  写一个简单的多线程模拟买票的程序  四个买票窗口,一共有100张票 */ class Tick implements Runnable{         private static  int tick=100;         private String window;         public  void windowName(String window){                 synchronized(Tick.class){              

MAC COCOA一个简单的多线程程序[2]

MAC COCOA一个简单的多线程程序[2] 使用RUNLOOP计数,实现一个时间计数器和事件at the same time 运行. STEP 1 H CODE: // // EDUAppDelegate.h // test_runloop_multithread // // Created by DMD on 23/6/14. // Copyright (c) 2014 EDU. All rights reserved. // #import <Cocoa/Cocoa.h> @interf

一个简单的多线程爬虫

   本文介绍一个简单的多线程并发爬虫,这里说的简单是指爬取的数据规模不大,单机运行,并且不使用数据库,但保证多线程下的数据的一致性,并且能让爬得正起劲的爬虫停下来,而且能保存爬取状态以备下次继续. 爬虫实现的步骤基本如下: 分析网页结构,选取自己感兴趣的部分; 建立两个Buffer,一个用于保存已经访问的URL,一个用户保存带访问的URL; 从待访问的Buffer中取出一个URL来爬取,保存这个URL中感兴趣的信息:并将这个URL加入已经访问的Buffer中,然后将这个URL中的所有外链URL

Java Tread多线程(0)一个简单的多线程实例

作者 : 卿笃军 原文地址:http://blog.csdn.net/qingdujun/article/details/39341887 本文演示,一个简单的多线程实例,并简单分析一下线程. 编程多线程时,一般步骤: 1)继承Thread函数. 2)覆盖run函数. 注意:1)main函数为主线程,main里面存放的是主线程的执行代码: Demo1为子线程,里面的run函数里面存放的是子线程需要执行的代码:其中,本文中主线程和子线程执行的优先级是一样的. 2)启动线程必须用start()启动,

大数据之网络爬虫-一个简单的多线程爬虫

   本文介绍一个简单的多线程并发爬虫,这里说的简单是指爬取的数据规模不大,单机运行,并且不使用数据库,但保证多线程下的数据的一致性,并且能让爬得正起劲的爬虫停下来,而且能保存爬取状态以备下次继续. 爬虫实现的步骤基本如下: 分析网页结构,选取自己感兴趣的部分; 建立两个Buffer,一个用于保存已经访问的URL,一个用户保存带访问的URL; 从待访问的Buffer中取出一个URL来爬取,保存这个URL中感兴趣的信息:并将这个URL加入已经访问的Buffer中,然后将这个URL中的所有外链URL

Linux下简单的多线程编程--线程池的实现

/* 写在前面的话: 今天刚“开原”,选择了一篇关于线程池的文件与大家分享,希望能对您学习有所帮助,也希望能与大家共同学习! 选择在这个特殊的时候注册并发文章也是有一些我个人特殊的意义的,看我的id(西游小学生.45)就知道了,哈哈.在这里也很感谢博客园的员工,刚发申请两分钟就同意了. */ 最近由于要写一个类似于QQ的程序,所以想到要用到多线程.既然要用多线程,那何不写一个线程池?于是上网搜了搜多线程的代码,发现大多都不是很完善,或者有些小bug.所以,在这里贴出一个完整的,经过我多重测试的,