内容:实现win32下的最基本多线程编程

使用函数:

#CreateThread#
创建线程
HANDLE WINAPI CreateThread(
LPSECURITY_ATTRIBUTES lpThreadAttributes,
SIZE_T dwStackSize,
LPTHREAD_START_ROUTINE lpStartAddress,
LPVOID lpParameter,
DWORD dwCreationFlags,
LPDWORD lpThreadID
);
函数说明:param1 线程内核对象安全属性,一般传入NULL表示使用默认设置
param2 表示线程栈空间大小。传入0,表示默认使用大小1MB
param3 新线程的线程函数地址,多个线程可以使用同一个函数地址
param4 传给线程函数的参数
param5 指定额外的标志来控制线程的创建,为0表示线程创建之后立即可以进行调度,如果为CREATE_SUSPENDED则表示线程创建以后暂停运行,这样无法调度,直到调用ResumeThread()
param6 返回线程的ID号,传入NULL表示不需要返回该线程ID号
注意:尽量使用 _beginthreadex()代替使用CreateThread().标准C运行库与多线程矛盾。

  

#WaitForMultipleObjects#
同时等待多个对象的触发,也可以用来事件的分别触发,定时触发。
DWORD WaitForMutilpleObjects(
DWORD nCount,
CONST HANDLE *lpHandles,
BOOL fWaitALL,
DWORD dwMilliseconds,
);
参数 nCount 句柄的最大数 最大值为MAXIMUM_WAIT_OBJECTS
HANDLE 句柄数组指针,类型可以为EVENT,Mutex,Process,Thread,Semaphore数组
bWaitAll 等待类型,如果为TRUE,则等待所有信号量再往下执行,FALSE当其中一个信号量有效时就向下执行
dwMilliseconds 超时事件 超时后就执行,如果为WSA_INFINTE永不超时,如果没有信号量就会死在这里。

实现代码:线程IMM_PCentry和Def_DeferredTaskEntry交替运行。本程序并未实现同步,只是简单的多线程操作。

 #include <windows.h>
#include <stdlib.h>
#include <stdio.h>
#include <process.h> #define SYN int index = ;
HANDLE hMainThread;
HANDLE hIMMthread;
HANDLE hMainThread_ID = ;
HANDLE hIMMthread_ID = ;
#ifdef SYN
HANDLE Mutex_Main;
HANDLE Mutex_Imm;
#endif void WINAPI IMM_PCentry(LPVOID lpParameter)
{
//WaitForSingleObject(hMutex, INFINITE); //第二个参数为INFINITE表示一直等待,直到拥有互斥对象
while (index < )
{
#ifdef SYN
WaitForSingleObject(Mutex_Main, INFINITE);
#endif
index = index + ;
printf("IMM_PCentry hello %d id%d\n", index, hIMMthread_ID);
#ifdef SYN
SetEvent(Mutex_Imm);
#endif
} } void WINAPI Def_DeferredTaskEntry(LPVOID lpParameter)
{
//WaitForSingleObject(hMutex, INFINITE); //第二个参数为INFINITE表示一直等待,直到拥有互斥对象
while (index < )
{
#ifdef SYN
WaitForSingleObject(Mutex_Imm, INFINITE);
#endif
index = index + ;
printf("Def_DeferredTaskEntry hello sharon6 %d id%d\n", index, hMainThread_ID);
#ifdef SYN
SetEvent(Mutex_Main);
#endif
} } int main(void)
{
#ifdef SYN
Mutex_Main = CreateEvent(NULL, , , NULL);
Mutex_Imm = CreateEvent(NULL, , , NULL);
SetEvent(Mutex_Imm);
#endif hMainThread = CreateThread(NULL, , IMM_PCentry, NULL, , &hMainThread_ID);
hIMMthread = CreateThread(NULL, , Def_DeferredTaskEntry, NULL, , &hIMMthread_ID);
WaitForSingleObject(hMainThread, INFINITE);
WaitForSingleObject(hIMMthread, INFINITE);
Sleep();
CloseHandle(hMainThread);
CloseHandle(hIMMthread);
return ;
}

未定义#define SYN时打印结果如下

index为两个线程的共享内存变量。
  Def_DeferredTaskEntry线程第一次结束后Count = Count + 1 = 1;
  IMM_Pcentry线程开始, 执行完 index = index + 1; 线程被Def_DeferredTaskEntry抢占IMM_Pcentry上下文保存了index = 2的值;
  Def_DeferredTaskEntry线程开始执行,执行到打印hello 7后,执行到index = index + 1,Def_DeferredTaskEntry线程又被IMM_Pcentry线程抢占,Def_DeferredTaskEntry线程保存线程上下文,包括index = 8;
  继续执行上次线程IMM_Pcentry执行的地方,恢复上下文环境,当时保存的是index = 2的值,此时被打印出来。线程IMM_Pcentry继续正常执行。

  可以发现,正是因为线程的不断切换,导致index不是每次都加一变化。

为了达到index正常加1的目的,于是利用信号量来实现线程的控制。增加#define SYN宏定义

#CreateEvent#
HANDLE CreateEvent(
LPSECURITY_ATTRIBUTES lpEventAttributes,//安全属性
BOOL bManualReset,//复位方式
BOOL bInitialState,//初始状态
LPCSTR ipName//对象名称
);
#SetEvent#
一种Win32系统编程事件API
CEvent::SetEvent
BOOL SetEvent(HANDLE hEvent);
其中hEvent表示句柄,返回值;如果操作成功,则返回非零值,否则为0.

可以看到打印结果,两个线程执行顺序得到了控制。注意这里并不是通过加锁来得到想要得结果。

windows多线程编程实现 简单(1)的更多相关文章

  1. windows多线程编程星球(一)

    以前在学校的时候,多线程这一部分是属于那种充满好奇但是又感觉很难掌握的部分.原因嘛我觉得是这玩意儿和编程语言无关,主要和操作系统的有关,所以这部分内容主要出现在讲原理的操作系统书的某一章,看完原理是懂 ...

  2. Windows多线程编程入门

    标签(空格分隔): Windows multithread programming 多线程 并发 编程 背景知识 在开始学习多线程编程之前,先来学习下进程和线程 进程 进程是指具有一定独立功能的程序在 ...

  3. Windows多线程编程总结

    1 内核对象 1 .1 内核对象的概念 内核对象是内核分配的一个内存块,这种内存块是一个数据结构,表示内核对象的各种特征.并且只能由内核来访问.应用程序若需要访问内核对象,需要通过操作系统提供的函数来 ...

  4. windows多线程编程(一)(转)

    源出处:http://www.cnblogs.com/TenosDoIt/archive/2013/04/15/3022036.html CreateThread:Windows的API函数(SDK函 ...

  5. Win32 API 多线程编程——一个简单实例(含消息参数传递)

    Win32 API进行程序设计具有很多优点:应用程序执行代码小,运行效率高,但是他要求程序员编写的代码较多,且需要管理所有系统提供给程序的资源,要求程序员对Windows系统内核有一定的了解,会占用程 ...

  6. windows多线程编程

    进程共同实现某个任务或者共享计算机资源, 它们之间存在两种关系: 1.同步关系, 指为了完成任务的进程之间, 因为需要在某些位置协调它们的执行顺序而等待, 传递消息产生的制约关系. 2.互斥关系, 进 ...

  7. Windows多线程编程入门笔记

    每次处理并行任务时,如果要等待用户输入或依赖外部(如与灿亨控制器响应),就应该为类似的操作单独创建一个线程,这样我们的程序才不会挂起无响应. 静态库和动态库 静态库是指在程序运行前就编译完成的库,如# ...

  8. Windows Socket 编程_ 简单的服务器/客户端程序

    转载自:http://blog.csdn.net/neicole/article/details/7459021 一.程序运行效果图 二.程序源代码 三.程序设计相关基础知识 1.计算机网络    2 ...

  9. Windows平台下的多线程编程

    线程是进程的一条执行路径,它包含独立的堆栈和CPU寄存器状态,每个线程共享所有的进程资源,包括打开的文件.信号标识及动态分配的内存等.一个进程内的所有线程使用同一个地址空间,而这些线程的执行由系统调度 ...

随机推荐

  1. project server 2016 新功能

    1.多时间轴 2.资源容量规划 3.资源请求

  2. 利用私有的API获得手机上所安装的所有应用信息(包括版本,名称,bundleID,类型)

    MobileCoreService这个系统的库,里面有个私有的类LSApplicationWorkspace ,利用运行时可以获得私有类里面的方法,- (id)allInstalledApplicat ...

  3. Android 面试题--Activity

    1.什么是 Activity?Activity是Android组件中最基本也是最为常见用的四大组件(Activity,Service服务,Content Provider内容提供,BroadcastR ...

  4. AngularJS 系列 02 - 模块

    引导目录: AngularJS 系列 学习笔记 目录篇 前言: 其实,在上篇文章介绍数据绑定的时候,我们的HelloWorld的代码案例中就已经使用了模块(module).哈哈. 本篇就着重介绍一下a ...

  5. 怎么知道Fragment属于哪个Activity呢?

    如果程序是一条线运行的,Fragment 中 getActivity() 是获取的上一个打开或者执行的Activity中的值.   多个Activity也是如此,就看顺序是怎么执行的,getActiv ...

  6. Visual Studio Emulator for Android 初体验

    Visual Studio Emulator for Android已经推出一段时间了,但一直没有用过.前两天下载安装用了下,整体感觉比谷歌自带的模拟器强多了.Visual Studio Emulat ...

  7. OpenStack Mitaka 版本中的 domain 和 admin

    OpenStack 的 Keystone V3 中引入了 Domain 的概念.引入这个概念后,关于 admin 这个role 的定义就变得复杂了起来. 本文测试环境是社区 Mitaka 版本. 1. ...

  8. [Top-Down Approach] Chatper 3 Notes

    这里留下空白,提醒自己,第一章第二章尚待整理回顾. 此处缺了3.6/3.7两节拥塞控制的内容

  9. 关于IOS调用微信支付jsapi不起作用的解决方法

    微信支付时,安卓机调用 jsapi可以支付,IOS就不行,点击立即支付,直接返回原立即支付页面,跟刷新页面差不多,解决方案很简单:两句话而已. 不得不说,微信支付坑太多了,我擦..... <sc ...

  10. VMWare Tools 和 Shared folder(共享文件夹)

    转自: http://www.51testing.com/html/38/225738-143732.html 使用vmwar下shared folders功能实现vmware中host与ghost间 ...