对这个两个常见的windows下的函数学习了一下:

//最简单的创建多线程实例
#include <stdio.h>
#include <windows.h>
//子线程函数
DWORD WINAPI ThreadFun(LPVOID pM)
{
    printf("子线程的线程ID号为:%d\n子线程输出Hello World\n", GetCurrentThreadId());
    ;
}
//主函数,所谓主函数其实就是主线程执行的函数。
int main()
{
    printf("     最简单的创建多线程实例\n");
    printf(" -- by MoreWindows( http://blog.csdn.net/MoreWindows ) --\n\n");

    HANDLE handle = CreateThread(NULL, , ThreadFun, NULL, , NULL);
    WaitForSingleObject(handle, INFINITE);
    ;
}

第一个 CreateThread

函数功能:创建线程

函数原型:

HANDLE    WINAPI   CreateThread(

LPSECURITY_ATTRIBUTES                lpThreadAttributes,

SIZE_T                                           dwStackSize,

LPTHREAD_START_ROUTINE             lpStartAddress,

LPVOID                                           lpParameter,

DWORD                                         dwCreationFlags,

LPDWORD                                       lpThreadId

);

函数说明:

第一个参数表示线程内核对象的安全属性,一般传入NULL表示使用默认设置。

第二个参数表示线程栈空间大小。传入0表示使用默认大小(1MB)。

第三个参数表示新线程所执行的线程函数地址,多个线程可以使用同一个函数地址。

第四个参数是传给线程函数的参数。

第五个参数指定额外的标志来控制线程的创建,为0表示线程创建之后立即就可以进行调度,如果为CREATE_SUSPENDED则表示线程创建后暂停运行,这样它就无法调度,直到调用ResumeThread()。

第六个参数将返回线程的ID号,传入NULL表示不需要返回该线程ID号。

函数返回值:

成功返回新线程的句柄,失败返回NULL。

第二个 WaitForSingleObject

函数功能:等待函数 – 使线程进入等待状态,直到指定的内核对象被触发。

函数原形:

DWORD   WINAPI    WaitForSingleObject(

HANDLE   hHandle,

DWORD   dwMilliseconds

);

函数说明:

第一个参数为要等待的内核对象。

第二个参数为最长等待的时间,以毫秒为单位,如传入5000就表示5秒,传入0就立即返回,传入INFINITE表示无限等待。

因为线程的句柄在线程运行时是未触发的,线程结束运行,句柄处于触发状态。所以可以用WaitForSingleObject()来等待一个线程结束运行。

函数返回值:

在指定的时间内对象被触发,函数返回WAIT_OBJECT_0。超过最长等待时间对象仍未被触发返回WAIT_TIMEOUT。传入参数有错误将返回WAIT_FAILED

CreateThread()函数是Windows提供的API接口,在C/C++语言另有一个创建线程的函数_beginthreadex(),在很多书上(包括《Windows核心编程》)提到过尽量使用_beginthreadex()来代替使用CreateThread(),

原因:_beginthreadex()函数在创建新线程时会分配并初始化一个_tiddata块。这个_tiddata块自然是用来存放一些需要线程独享的数据。事实上新线程运行时会首先将_tiddata块与自己进一步关联起来。然后新线程调用标准C运行库函数如strtok()时就会先取得_tiddata块的地址再将需要保护的数据存入_tiddata块中。这样每个线程就只会访问和修改自己的数据而不会去篡改其它线程的数据了。因此,如果在代码中有使用标准C运行库中的函数时,尽量使用_beginthreadex()来代替CreateThread()

  getbuffer是为了让你使用CString类中,保存字符串缓冲区的那块指针.   
  至于releasebuffer,在MSDN中有这样一句话.   
  If   you   use   the   pointer   returned   by   GetBuffer   to   change   the   string   contents,   you   must   call   ReleaseBuffer   before   using   any   other   CString   member   functions.   
  在对GetBuffer返回的指针使用之后需要调用ReleaseBuffer,这样才能使用其他Cstring的operations。否则会发生错误.

GetBuffer(0)返回的是指向CString对象所构造的字串指针,为GetBuffer(0)由系统自动计算字串所要的空间长度,但要求是规则的含\0字串,否则得自己给出长度,如str.GetBuffer(20)。

LPTSTR GetBuffer( int nMinBufLength ) 这个函数是CString 的一个比较实用的函数,请看如下示例:

GetBuffer(int nMinBufLength);的参数问题一直比较困扰人,网站的资料还像也不是太好给的,请看msdn解释

Parameters
nMinBufLength
The minimum size of the character buffer in characters. This value does not include space for a null terminator.
得到buffer的最小长度,当然这是由我们自己设定的一个参数,其原型定义如下:
LPTSTR CString::GetBuffer(int nMinBufLength)
{
 ASSERT(nMinBufLength >= 0);

if (GetData()->nRefs > 1 || nMinBufLength > GetData()->nAllocLength)
 {
#ifdef _DEBUG
  // give a warning in case locked string becomes unlocked
  if (GetData() != _afxDataNil && GetData()->nRefs < 0)
   TRACE0("Warning: GetBuffer on locked CString creates unlocked CString!/n");
#endif
  // we have to grow the buffer
  CStringData* pOldData = GetData();
  int nOldLen = GetData()->nDataLength;   // AllocBuffer will tromp it
  if (nMinBufLength < nOldLen)
   nMinBufLength = nOldLen;
  AllocBuffer(nMinBufLength);
  memcpy(m_pchData, pOldData->data(), (nOldLen+1)*sizeof(TCHAR));
  GetData()->nDataLength = nOldLen;
  CString::Release(pOldData);
 }
 ASSERT(GetData()->nRefs <= 1);

// return a pointer to the character storage for this string
 ASSERT(m_pchData != NULL);
 return m_pchData;
}

上面的代码已经比较清楚了,当设定的长度小于原字符串长度时,nMinBufLength = nOldLen,然后分配相应的内存,当你设定的长度大于原字符串本身的长度时就要分配一块比较大的空间出来,这时你可以实现字符串对接的操作。

GetBuffer()主要作用是将字符串的缓冲区长度锁定,releaseBuffer则是解除锁定,使得CString对象在以后的代码中继续可以实现长度自适应增长的功能。

CString ::GetBuffer有两个重载版本:

LPTSTR GetBuffer( );LPTSTR GetBuffer(int nMinBufferLength);

在第二个版本中,当设定的长度小于原字符串长度时,nMinBufLength = nOldLen,该参数会被忽

略,不分配内存,指向原CString;当设定的长度大于原字符串本身的长度时就要重新分配(reallocate)一块比较大的空间出来。而调用第一个版本时,应如通过传入0来调用第二个版本一样。

是否需要在GetBufer后面调用ReleaseBuffer(),是根据你的后面的程序是否需要继续使用该字符串变量,并且是否动态改变其长度而定的。如果你GetBuffer以后程序自函数就退出,局部变量都不存在了,调用不调用ReleaseBuffer没什么意义了。

这是一个非常容易被用错的函数,主要可能是由于大家对它的功能不太了解。其实点破的话,也不是那么深奥。
    GetBuffer(int size)是用来返回一个你所指定大小可写内存的成员方法。它和被重载的操作符LPCTSTR还是有点本质区别的,LPCTSTR是直接返回一个只读内存的指针,而GetBuffer则是返回一个可以供调用者写入的内存,并且,你可以给定大小。下面是个简单的,但也是非常典型的例子:
    int readFile(CString& str, const CString& strPathName)
    {
        FILE* fp = fopen(strPathName, "r"); // 打开文件
        fseek(fp, 0, SEEK_END);
        int nLen = ftell(fp); // 获得文件长度
        fseek(fp, 0, SEEK_SET); // 重置读指针
        char* psz = str.GetBuffer(nLen);
        fread(psz, sizeof(char), nLen, fp); //读文件内容
        str.ReleaseBuffer(); //千万不能缺少
        fclose(fp);
    }
    上面的函数是GetBuffer函数最典型的用法了,其实它就相当于申请一块nLen大小的内存,只不过,这块内存是被引用在CString对象的内部而已,这是非常有效的一种用法,如果不直接用GetBuffer函数来申请的话,那么你必须用new操作符(或者malloc()函数)在CString的外部申请,然后再将申请的内存拷贝到CString对象中,显然这是一个非常冗余的操作,会使你函数的效率大大下降。
    ReleaseBuffer函数是用来告诉CString对象,你的GetBuffer所引用的内存已经使用完毕,现在必须对它进行封口,否则 CString将不会知道它现在所包含的字符串的长度,所以在使用完GetBuffer之后,必须立即调用ReleaseBuffer函数重置 CString的内部属性,其实也就是头部信息。

补充一下:

GetBuffer说白了就两个功能:

1:就是将CString里面的内存交到外部一个来处理,外部可以直接修改它的内容。

2:重新修改CString的内存大小,这个数值不包含null结尾符。

另一个典型的用法:就是将CString里面的内容变为int或long型,需要先获取里面的内存指针。这样就可以先GetBuffer(内存大小)方便直接转换。

如果在外部修改了CString里面的内容,在重新使用CString之前,需调用ReleaseBuffer()也就是说,ReleaseBuffer不需要每次都调用。

MSDN原文:

If you use the pointer returned by GetBuffer to change the string contents, you must call ReleaseBuffer before using any other CSimpleStringT member methods.

The buffer memory is automatically freed when the CSimpleStringT object is destroyed.

If you keep track of the string length yourself, you should not append the terminating null character. You must, however, specify the final string length when you release the buffer with ReleaseBuffer. If you do append a terminating null character, you should pass –1 (the default) for the length toReleaseBuffer, and ReleaseBuffer will perform a strlen on the buffer to determine its length.

CreateThread函数&amp;&amp;CString::GetBuffer函数的更多相关文章

  1. CreateThread函数&&CString::GetBuffer函数

    对这个两个常见的windows下的函数学习了一下: //最简单的创建多线程实例 #include <stdio.h> #include <windows.h> //子线程函数 ...

  2. Sql Server函数全解<二>数学函数

    阅读目录 1.绝对值函数ABS(x)和返回圆周率的函数PI() 2.平方根函数SQRT(x) 3.获取随机函数的函数RAND()和RAND(x) 4.四舍五入函数ROUND(x,y) 5.符号函数SI ...

  3. Sql Server函数全解<一>字符串函数

    阅读目录 1.ASCII()函数 2.CHAR()函数 3.LEFT()函数 4.RIGHT()函数 5.LTRIM()函数 6.RTRIM()函数 7.STR()函数 8.字符串逆序的函数REVER ...

  4. JS函数 -- 功能,语法,返回值,匿名函数,自调用匿名函数,全局变量与局部变量,arguments的使用

    “JavaScript设计得最出色的就是它的函数的实现.” -- <JavaScript语言精粹> 函数包含一组语句,它们是JS的基础模块单元,用于指定对象的行为.一般来说,所谓编程,就是 ...

  5. Sql Server函数全解(一)字符串函数

    字符串函数用于对字符和二进制字符进行各种操作 1.ASCII()函数  ASCII(character_expression)函数用于返回字符串表达式中最左侧的ASCII代码值.参数character ...

  6. js中的全局变量和静态变量的使用, js 的调试?- 如果js出错, js引擎 就会停止, 这会 导致 后面的 html中 refer 该函数时, 会报错 函数为定义!!

    效果里面的函数, 如show, hide,slideDown等, 这些都叫 "效果"函数, 但是里面可以包含动画, 也可以 不包含动画. 动画,是指 元素 的内容 是 逐渐 显示/ ...

  7. 《zw版·Halcon-delphi系列原创教程》 Halcon分类函数009,Measure,测量函数

    <zw版·Halcon-delphi系列原创教程> Halcon分类函数009,Measure,测量函数 为方便阅读,在不影响说明的前提下,笔者对函数进行了简化: :: 用符号“**”,替 ...

  8. C++调用动态库中的虚基类成员函数时总是进错函数

    原创文章,转载请注明作者与本文原始URL. 问题描述:最近遇到这样一个问题,在调用C++的一个成员函数时,总是进错函数.在调用 pMsg->GetMsgContent() 的时候,总是进入到 p ...

  9. jQuery1.11源码分析(9)-----初始化jQuery对象的函数和关联节点获取函数

    这篇也没什么好说的,初始化jQuery对象的函数要处理多种情况,已经被寒冬吐槽烂了.关联节点获取函数主要基于两个工具函数dir和sibling,前者基于指定的方向遍历,后者则遍历兄弟节点(真的不能合并 ...

随机推荐

  1. 开源调度框架Quartz最佳实践

    开源调度框架Quartz最佳实践 Quartz是一个Java调度框架,当前的最新版本为2.2.1. 以Quartz 2.2.1版为例,Quartz最佳实践(用于生产系统)总结如下: 1.跳过更新检查Q ...

  2. java调用phantomjs采集ajax加载生成的网页

    java调用phantomjs采集ajax加载生成的网页 日前有采集需求,当我把所有的对应页面的链接都拿到手,准备开始根据链接去采集(写爬虫爬取)对应的终端页的时候,发觉用程序获取到的数据根本没有对应 ...

  3. sql partition by 的使用

    select a.bs_sn, a.bs_bd_no, a.bs_bk_code, a.bs_kind_no, a.bs_flag, b.det_flag, c.bp_in_no, c.bp_name ...

  4. NuGet在2015中的使用

    NuGet Package Restore  https://docs.nuget.org/Consume/Package-Restore 以https://github.com/andburn/hd ...

  5. CFF前端沙龙总结

    一. -OOCSS + Sass ——大漠 1. OOCSS 结构<=>皮肤 分离 容器<=>内容 分离 2. Sass 工具.处理器 SCSS(CSS风格)<=> ...

  6. 带你走进EJB--那些跟EJB容器相关的那些Java概念

    最近在对EJB的相关内容进行总结,在总结的过程中发现对容器的概念并不是很理解,因为EJB本身就是一个容器,但是容器到底是用来做什么的?它跟我们之前所了解的组件,框架,包,类等都有什么关系?接下来主要是 ...

  7. TCSRM 593 div2(1000)(dp)

    Problem Statement      The pony Rainbow Dash wants to choose her pet. There are N animals who want t ...

  8. Awesome Javascript(中文翻译版)

    [导读]:GitHub 上有一个 Awesome – XXX 系列的资源整理.awesome-javascript 是 sorrycc 发起维护的 JS 资源列表,内容包括:包管理器.加载器.测试框架 ...

  9. JdbcTemplate查询数据 三种callback之间的区别

    JdbcTemplate针对数据查询提供了多个重载的模板方法,你可以根据需要选用不同的模板方法. 如果你的查询很简单,仅仅是传入相应SQL或者相关参数,然后取得一个单一的结果,那么你可以选择如下一组便 ...

  10. svn is already under version control问题解决

    svn ci 时出现 xx is already under version control,然后无法提交,出现这个问题的原因是你所提交的文件或目录是其他SVN的东西,即下面有.svn的目录,需要先把 ...