多线程编程示例(结合实例)

1.CreateThread与_beginthreadex

#pragma once

#include<cstdio>
#include<Windows.h>
#include<crtdbg.h>
#include<process.h>

//子线程函数
DWORD WINAPI ThreadFun1(LPVOID pM)
{
    printf("子线程的线程ID号为:%d\nHello world!\n",GetCurrentThreadId());
    return 0;
}

void fun1()
{
    printf("简单多线程实例!\n\n");

    /*
       CreateThread参数解析
       1:线程内核安全属性
       2:线程栈空间大小
       3:线程执行函数地址
       4:传给线程执行函数参数
       5:线程创建控制参数(CREATE_SUSPENDED)
       6:线程ID号
    */
    HANDLE handle = CreateThread(NULL, 0, ThreadFun1, NULL, 0, NULL);
    WaitForSingleObject(handle, INFINITE);
    CloseHandle(handle);
}

//设置计数全局变量
int COUNT = 0;

//子线程函数
unsigned int _stdcall ThreadFun2(PVOID pM)
{
    ++COUNT;
    printf("子线程的线程ID号为:%d,报数为%d\nHello world!\n", GetCurrentThreadId(),COUNT);
    return 0;
}

void fun2()
{
    printf("简单多线程实例!\n\n");

    const int THREAD_NUM = 5;
    HANDLE handle[THREAD_NUM];

    for (size_t i = 0; i < THREAD_NUM; i++)
    {
        handle[i] = (HANDLE)_beginthreadex(NULL, 0, ThreadFun2, NULL, 0, NULL);
    }
    WaitForMultipleObjects(THREAD_NUM, handle, TRUE, INFINITE);
}

int main(void)
{
    //使用CreateThread
    //fun1();

    //使用_beginthreadex
    //推荐使用原因为:使用标准C运行库函数时,易发生race condition
    //使用_beginthreadex可以避免数据被其他线程篡改
    //更加合理的解释可以参考Win32多线程编程
    fun2();

    //检测内存泄漏
    _CrtDumpMemoryLeaks();
    return 0;
}

其中执行fun2结果为:(蛮有趣的,不加锁竟然这么直观)

2.原子操作

#pragma once

#include<cstdio>
#include<Windows.h>
#include<crtdbg.h>
#include<process.h>

volatile long COUNT = 0;
const int THREAD_NUM = 500;

unsigned int _stdcall ThreadFun(LPVOID pM)
{
    Sleep(50);
    //++COUNT;
    InterlockedIncrement((LPLONG)&COUNT); //使用原子锁替换
    Sleep(50);
    return 0;
}

void fun1()
{
    HANDLE handle[THREAD_NUM];

    for (size_t i = 0; i < THREAD_NUM; i++)
    {
        handle[i] = (HANDLE)_beginthreadex(NULL, 0, ThreadFun, NULL, 0, NULL);
    }
    WaitForMultipleObjects(THREAD_NUM, handle, TRUE, INFINITE);
    printf("有%d个线程启动,记录结果为%d", THREAD_NUM, COUNT);
}

int main()
{
    //test1
    fun1(); //易发现线程启动数和计数不匹配

    //检测内存泄漏
    _CrtDumpMemoryLeaks();
    return 0;
}

这里++操作在汇编层面是分成三层的:(1)取值由内存存至寄存器;(2)寄存器中进行操作;(3)数值由寄存器转储至内存。这个过程容易出现问题。

但是使用原子操作在只有50个线程启动时准确,但是上限调至500次时,线程启动数和计数又不一致。

时间: 2024-10-10 13:19:50

多线程编程示例(结合实例)的相关文章

多线程编程示例2(结合实例)

5.互斥量(Mutex) #pragma once #define _CRTDBG_MAP_ALLOC #include<cstdio> #include<Windows.h> #include<crtdbg.h> #include<process.h> unsigned int count = 0; const unsigned int threadnum = 50; HANDLE Mutex; CRITICAL_SECTION ThreadPar; un

Python threading多线程编程示例

Python 的多线程有两种实现方法: 函数,线程类 1.函数 调用 thread 模块中的 start_new_thread() 函数来创建线程,以线程函数的形式告诉线程该做什么 # -*- coding: utf-8 -*- import thread def f(name): #定义线程函数 print "this is " + name if __name__ == '__main__': thread.start_new_thread(f, ("thread1&qu

多线程编程示例4(写者读者问题)

读者写者也是一个非常著名的同步问题. 读者写者问题描述非常简单,有一个写者很多读者,多个读者可以同时读文件,但写者在写文件时不允许有读者在读文件,同样有读者在读文件时写者也不去能写文件. #pragma once #define _CRTDBG_MAP_ALLOC #include<cstdio> #include<Windows.h> #include<crtdbg.h> #include<process.h> int currreadernum = 0;

Java多线程编程4--Lock的实例--实现生产者/消费者模式:一对一、多对多交替打印

1.实现生产者/消费者模式:一对一交替打印 public class MyService { private ReentrantLock lock= new ReentrantLock(); private Condition condition = lock.newCondition(); private boolean hasValue = false; public void set() { try{ lock.lock(); while (hasValue == true) { cond

Siege——多线程编程最佳实例

在英语中,“Siege”意为围攻.包围.同时Siege也是一款使用纯C语言编写的开源WEB压测工具,适合在GNU/Linux上运行,并且具有较强的可移植性.之所以说它是多线程编程的最佳实例,主要原因是Siege的实现原理中大量运用了多线程的各种概念.Siege代码中用到了互斥锁.条件变量.线程池.线程信号等很多经典多线程操作,因此对于学习多线程编程也大有裨益.最近花了一些时间学习到了Siege的源代码,本文将介绍一下Siege压测工具的内部原理,主要供系统测试同学.以及学习多线程编程的同学们参考

linux下多线程编程

最近研究mysql源码,各种锁,各种互斥,好在我去年认真学了<unix环境高级编程>, 虽然已经忘得差不多了,但是学过始终是学过,拿起来也快.写这篇文章的目的就是总结linux 下多线程编程,作为日后的参考资料. 本文将介绍linux系统下多线程编程中,线程同步的各种方法.包括: 互斥量(mutex) 读写锁 条件变量 信号量 文件互斥 在介绍不同的线程同步的方法之前,先简单的介绍一下进程和线程的概念, 它们的优缺点,线程相关的API,读者——写者问题和哲学家就餐问题. 基础知识 1. 进程和

java多线程编程从入门到卓越(超详细总结)

导读:java多线程编程不太熟?或是听说过?或是想复习一下?找不到好的文章?别担心我给你们又安利一波,文章内容很全,并且考虑到很多开发中遇到的问题和解决方案.循环渐进,通俗易懂,文章较长,建议收藏再看! 往期精彩放送:一文搞定Java的输入输出流等常见流 一文搞定Java集合类,你还在为Java集合类而烦恼吗? 文章目录 1.多线程的概念 2.多线程并发 3.多线程程序设计 继承Thread类创建线程 新建类实现Runnable接口创建线程 改进(匿名内部类方式) 获取线程的名字和当前线程对象

多线程异步编程示例和实践-Thread和ThreadPool

说到多线程异步编程,总会说起Thread.ThreadPool.Task.TPL这一系列的技术.总结整理了一版编程示例和实践,分享给大家. 先从Thread和ThreadPool说起: 1. 创建并启动线程 2. 暂停线程 当前线程在执行Thread.Sleep方法时,会等待指定的时间(1000ms)此时,当前线程处于阻塞状态:WaitSleepJoin 3. 线程等待 当程序运行时,启动了一个耗时较长的线程打印数字,每次打印输出前需要等待1000ms,我们在主程序中调用ThreadJoin方法

java多线程编程实例

[转]这篇文章主要介绍了java多线程编程实例,分享了几则多线程的实例代码,具有一定参考价值,加深多线程编程的理解还是很有帮助的,需要的朋友可以参考下. 1.三个售票窗口同时出售20张票程序分析:    (1)票数要使用同一个静态值    (2)为保证不会出现卖出同一个票数,要java多线程同步锁.设计思路:    (1)创建一个站台类Station,继承Thread,重写run方法,在run方法里面执行售票操作!售票要使用同步锁:即有一个站台卖这张票时,其他站台要等这张票卖完!    (2)创