windows环境下线程编程(C++实现同步与互斥)

简介: Windows系统为我们提供了相关API,我们可以使用他们来进行多线程编程。

Windows系统为我们提供了相关API,我们可以使用他们来进行多线程编程。

1.创建一个线程,参数解释如下:

HANDLE CreateThread(
    LPSECURITY_ATTRIBUTES lpThreadAttributes,//SD:线程安全相关的属性,常置为NULL
    SIZE_T dwStackSize,//initialstacksize:新线程的初始化栈的大小,可设置为0
    LPTHREAD_START_ROUTINE lpStartAddress,//threadfunction:被线程执行的回调函数,也称为线程函数
    LPVOID lpParameter,//threadargument:传入线程函数的参数,不需传递参数时为NULL
    DWORD dwCreationFlags,//creationoption:控制线程创建的标志
    LPDWORD lpThreadId//threadidentifier:传出参数,用于获得线程ID,如果为NULL则不返回线程ID
)

2.创建一个信号量,参数解释如下:

HANDLE CreateSemaphore(
 LPSECURITY_ATTRIBUTES lpSemaphoreAttributes, // 安全属性指针
 LONG lInitialCount, // 初始计数
 LONG lMaximumCount, // 最大计数
 LPCTSTR lpName // 对象名指针
);

3.P操作,参数解释如下:

DWORD WaitForSingleObject(
HANDLE hObject, //指明一个内核对象的句柄
DWORD dwMilliseconds); //等待时间

4.V操作,参数解释如下:

ReleaseSemaphore(
    HANDLE hSemaphore,
    LONG lReleaseCount,
    LPLONG lpPreviousCount
    );
hSemaphore 是要增加的信号量句柄。
lReleaseCount 是增加的计数。
lpPreviousCount 是增加前的数值返回。

5:基础示例:

#include <iostream>
#include <windows.h>
using namespace std;
DWORD WINAPI Fun(LPVOID lpParamter)//子线程
{
    for (int i = 0; i < 10; i++)
    {
        cout << "A Thread Fun Display!" << endl;
        Sleep(200);//每次休眠200ms
    }
    return 0;
}
int main()
{
    HANDLE hThread = CreateThread(NULL, 0, Fun, NULL, 0, NULL);//创建一个最简单的子线程
    CloseHandle(hThread);//关闭句柄
    for (int i = 0; i < 10; i++)
    {
        cout << "Main Thread Display!" << endl;
        Sleep(500);//每次休眠500ms
    }
    system("pause");
    return 0;
}

6:进阶示例:

问题描述:桌上有一空盘,最多允许存放一个水果。爸爸可向盘中放一个苹果或放一个桔子,儿子专等吃盘中的桔子,女儿专等吃苹果。 编写Windows下父亲儿子女儿放取水果进程同步的演示程序。

#include<iostream>
#include <stdio.h>
#include<string.h>
#include<windows.h>
using namespace std;
HANDLE g_apple = 0;//女儿线程互斥:表示可否取苹果
HANDLE g_orange = 0;//儿子线程互斥:表示可否取桔子
HANDLE g_hMutex = 0; //父亲线程互斥:表示可否向盘中放水果
bool g_continue = true; //控制程序运行和结束
DWORD WINAPI Father(LPVOID); //父亲线程
DWORD WINAPI Son(LPVOID);//儿子线程
DWORD WINAPI Daughter(LPVOID);//女儿线程
int main()
{
    //创建各个信号量
    g_orange = CreateSemaphore(NULL, 0, 1, NULL);
    g_apple = CreateSemaphore(NULL, 0, 1, NULL);
    g_hMutex = CreateSemaphore(NULL, 1, 1, NULL);
    DWORD threadID[3];
    HANDLE hThreads[3];
    //创建父亲线程
    hThreads[0] = CreateThread(NULL, 0, Father, NULL, 0, &threadID[0]);
    if (hThreads == NULL) return -1;
    //创建儿子线程
    hThreads[1] = CreateThread(NULL, 0, Son, NULL, 0, &threadID[1]);
    if (hThreads == NULL) return -1;
    //创建女儿线程
    hThreads[2] = CreateThread(NULL, 0, Daughter, NULL, 0, &threadID[2]);
    if (hThreads == NULL) return -1;
    while (g_continue){
        if (getchar()){  //按回车后终止程序运行
            g_continue = false;
        }
    }
    return 0;
}
//父亲线程
DWORD WINAPI Father(LPVOID lpPara)
{
    while (g_continue){
        WaitForSingleObject(g_hMutex, INFINITE);//INFINITE表示无限等待,一直等到当g_hMutex为1时才进行下面操作
        int m = rand() % 2;//rand取随机数,随机放苹果或者桔子
        if (m == 1) {
            cout<< "父亲放入一个苹果!" <<endl;
            Sleep(1500);
            ReleaseSemaphore(g_apple, 1, NULL);
        }
        else{
            cout<< "父亲放入一个桔子!" <<endl;
            Sleep(1500);
            ReleaseSemaphore(g_orange, 1, NULL);
        }
    }
    return 0;
}
//女儿线程
DWORD WINAPI Daughter(LPVOID lpPara)
{
    while (g_continue){
        WaitForSingleObject(g_apple, INFINITE);
        cout<< "女儿吃到一个苹果!" <<endl;
        Sleep(1500);
        ReleaseSemaphore(g_hMutex, 1, NULL);
    }
    return 0;
}
//儿子线程
DWORD WINAPI Son(LPVOID lpPara)
{
    while (g_continue){
        WaitForSingleObject(g_orange, INFINITE);
        cout<< "儿子吃到一个桔子!" <<endl;
        Sleep(1500);
        ReleaseSemaphore(g_hMutex, 1, NULL);
    }
    return 0;
}
相关文章
|
9月前
|
安全 算法 Java
Java 多线程:线程安全与同步控制的深度解析
本文介绍了 Java 多线程开发的关键技术,涵盖线程的创建与启动、线程安全问题及其解决方案,包括 synchronized 关键字、原子类和线程间通信机制。通过示例代码讲解了多线程编程中的常见问题与优化方法,帮助开发者提升程序性能与稳定性。
385 0
|
12月前
|
存储 算法 C++
Windows共享文件:探秘C++实现的B树索引算法奇境
在数字化时代,Windows共享文件的高效管理至关重要。B树算法以其自平衡多路搜索特性,在文件索引与存储优化中表现出色。本文探讨B树在Windows共享文件中的应用,通过C++实现具体代码,展示其构建文件索引、优化数据存储的能力,提升文件检索效率。B树通过减少磁盘I/O操作,确保查询高效,为企业和个人提供流畅的文件共享体验。
|
6月前
|
Ubuntu API C++
C++标准库、Windows API及Ubuntu API的综合应用
总之,C++标准库、Windows API和Ubuntu API的综合应用是一项挑战性较大的任务,需要开发者具备跨平台编程的深入知识和丰富经验。通过合理的架构设计和有效的工具选择,可以在不同的操作系统平台上高效地开发和部署应用程序。
266 11
|
安全 程序员 编译器
【实战经验】17个C++编程常见错误及其解决方案
想必不少程序员都有类似的经历:辛苦敲完项目代码,内心满是对作品品质的自信,然而当静态扫描工具登场时,却揭示出诸多隐藏的警告问题。为了让自己的编程之路更加顺畅,也为了持续精进技艺,我想借此机会汇总分享那些常被我们无意间忽视却又导致警告的编程小细节,以此作为对未来的自我警示和提升。
1540 102
|
存储 缓存 C++
C++ 容器全面剖析:掌握 STL 的奥秘,从入门到高效编程
C++ 标准模板库(STL)提供了一组功能强大的容器类,用于存储和操作数据集合。不同的容器具有独特的特性和应用场景,因此选择合适的容器对于程序的性能和代码的可读性至关重要。对于刚接触 C++ 的开发者来说,了解这些容器的基础知识以及它们的特点是迈向高效编程的重要一步。本文将详细介绍 C++ 常用的容器,包括序列容器(`std::vector`、`std::array`、`std::list`、`std::deque`)、关联容器(`std::set`、`std::map`)和无序容器(`std::unordered_set`、`std::unordered_map`),全面解析它们的特点、用法
C++ 容器全面剖析:掌握 STL 的奥秘,从入门到高效编程
|
存储 机器学习/深度学习 编译器
【C++终极篇】C++11:编程新纪元的神秘力量揭秘
【C++终极篇】C++11:编程新纪元的神秘力量揭秘
Java 线程同步的四种方式,最全详解,建议收藏!
本文详细解析了Java线程同步的四种方式:synchronized关键字、ReentrantLock、原子变量和ThreadLocal,通过实例代码和对比分析,帮助你深入理解线程同步机制。关注【mikechen的互联网架构】,10年+BAT架构经验倾囊相授。
Java 线程同步的四种方式,最全详解,建议收藏!
|
存储 算法 C++
深入浅出 C++ STL:解锁高效编程的秘密武器
C++ 标准模板库(STL)是现代 C++ 的核心部分之一,为开发者提供了丰富的预定义数据结构和算法,极大地提升了编程效率和代码的可读性。理解和掌握 STL 对于 C++ 开发者来说至关重要。以下是对 STL 的详细介绍,涵盖其基础知识、发展历史、核心组件、重要性和学习方法。
|
存储 安全 算法
深入理解C++模板编程:从基础到进阶
在C++编程中,模板是实现泛型编程的关键工具。模板使得代码能够适用于不同的数据类型,极大地提升了代码复用性、灵活性和可维护性。本文将深入探讨模板编程的基础知识,包括函数模板和类模板的定义、使用、以及它们的实例化和匹配规则。
|
供应链 安全 NoSQL
PHP 互斥锁:如何确保代码的线程安全?
在多线程和高并发环境中,确保代码段互斥执行至关重要。本文介绍了 PHP 互斥锁库 `wise-locksmith`,它提供多种锁机制(如文件锁、分布式锁等),有效解决线程安全问题,特别适用于电商平台库存管理等场景。通过 Composer 安装后,开发者可以利用该库确保在高并发下数据的一致性和安全性。
256 6

热门文章

最新文章

下一篇
开通oss服务