Tag Archives: 多线程

当Printf遇到多线程

====================================================================

我注意到有很多人通过关键字”printf 多线程”搜索到了我的这篇文章,我也意识到有很多Linux和Windows程序员在编写多线程程序中使用printf导致的种种问题。我猜测这与printf设计时的不可重入性有关,虽然我在文中用嵌入式的串口打印函数作为类比,可是这两个或许还不是一回事。
如果你遇到了这个问题,你可以尝试以下方法,即使用多线程运行时库(Mulit-Thread Runtime Library):

1、VC环境
Project-> Settings-> C/C++-> Code   Generation-> use   run-time   library
如果希望在多线程中使用,那么要选择multithreaded dll
当然如果你只是作为调试,可以使用TRACE宏。

2、Linux环境
Linux环境中如何设置运行时库的参数我不是非常清楚,不过只要保证调用的是多线程运行时库即可。可是,Linux会有这个问题么?

3、更通用的方法
更通用的办法就是使用互斥锁、信号量等方法,不过这可能会改变程序运行的本意。

 

以下才是原文的正文,不过如果你只是来解决以上问题的,本文就对你没有价值了:

====================================================================

本文作者:云飞工作室(YunFei Studio),戴晓天

联系方式:Automatic.dai@gmail.com

原文地址:www.YFworld.com


一、本文背景

Printf()这个函数我想大家再熟悉不过了,可是对于如何在多线程中使用Printf(),各位可能就没怎么接触过了。本文以VC6.0为开发平台,旨在利用多线程完成一个最简单的任务:在屏幕上一直输出”Hello,world!”。
因为个人水平有限,本文涉及的内容非常肤浅,不过我还是尽量将原理讲清楚,希望对初学者略有帮助。

为了提高大家的兴趣、降低理解难度,文章的结构也是几经修改。考虑到本文阅读者可能对于多线程不怎
么了解,本文将首先介绍Win32多线程编程。

二、多线程概述

2.1 进程与线程

在操作系统中,一个进程就是一个程序的实例。当你双击打开一个程序之后,实际上就启动了一个进程。该进程将程序代码装载至RAM,并运行、管理该实例。而线程是进程的最小分割,好比运行一个盖楼房的程序进程,需要各有分工,有的人打地基,有的人刷水泥,有的人搬材料一样。这里,每一个人都是一个线程。相比单线程(一个人盖楼房),多线程(几个人配合盖楼房)可以显著提高系统运行的效率。线程彼此独立工作,却有相关性,比如打地基的要等搬材料的把材料运过来,才可以施工。这就说明,线程之间有时需要彼此配合完成任务,这就需要进程间通讯(IPC)。

2.2 Windows多线程编程

在Windows下使用多线程,实际上就是通过调用Windows提供的应用程序接口API来完成特定任务。其中,最基本的是创建一个多线程,该函数的原型为:

HANDLE CreateThread(
  LPSECURITY_ATTRIBUTES lpThreadAttributes,  // pointer to security attributes
  DWORD dwStackSize,                         // initial thread stack size
  LPTHREAD_START_ROUTINE lpStartAddress,     // pointer to thread function
  LPVOID lpParameter,                        // argument for new thread
  DWORD dwCreationFlags,                     // creation flags
  LPDWORD lpThreadId                         // pointer to receive thread ID
);

Read more »