第十五章、多线程

15.1线程创建函数

创建线程可以利用系统提供的API函数:CreateThread函数来完成。

HANDLE CreateThread(
  LPSECURITY_ATTRIBUTES lpThreadAttributes,  
  DWORD dwStackSize,        // 初始化线程大小,若为0时使用默认大小
  LPTHREAD_START_ROUTINE lpStartAddress, //新线程起始地址
  LPVOID lpParameter,       // 给新创建的线程传递参数
  DWORD dwCreationFlags,    
  LPDWORD lpThreadId        // 接收线程ID
);

第一个参数若为NULL,让该线程使用默认的安全性;如果将SECURITY_ATTRIBUTES结构体的bInheritHandle成员初始化为TRUE,那么所有的子进程都能够继承该线程对象的句柄。
第五个参数控制线程创建的附加标记,如果该值是CREATE_SUSPENDED,那么线程创建后处于暂停状态;如果为0,表示线程在创建之后立即运行。

15.2简单多线程示例

新建一个Win32 Console Application类型的工程,取名为MultiThread。并给该工程添加一个C++源文件:MultiThread.cpp。

#include<windows.h>
#include<iostream>
DWORD WINAPI Fun1Proc(LPVOID lpParameter);
void main()
{
    HANDLE hThread1;
    hThread1=CreateThread(NULL,0,Fun1Proc,NULL,0,NULL);
    CloseHandle(hThread1);
    count<<"main thread is running"<<endl;
}
//线程一的入口函数
DWORD WINAPI Fun1Proc(LPVOID lpParameter)
{
    count<<"thread1 is running"<<endl;
    return 0;
}

//实际上调用CloseHandle并没有终止新创建的线程,只是在主线程中对新创建的线程的引用关闭了,系统就会递减该线程内核对象的使用计数。运行结果如图。主程序是运行了,但是没有看到thread1 is running这句话。主要是因为主线程执行完毕后,进程就退出了;新创建的线程一还没有执行就退出了。
在这里插入图片描述
//为了让新创建的线程可以执行,需要让主线程暂停执行,操作系统就会从等待运行的线程队列中选择一个线程来执行,这时新创建的线程1就会得到机会执行。让某个线程暂停执行,可以调用Sleep函数:
VOID Sleep(DWORD dwMilliseconds);
//参数是以毫秒为单位

//在main函数最后加上:
Sleep(10);
//运行结果如图。
在这里插入图片描述
//下面让主线程和线程一交替执行,同时为控制循环次数,定义一个变量,当变量达到给定值时就停止循环。

#include<windows.h>
#include<iostream>
int index=0;
DWORD WINAPI Fun1Proc(LPVOID lpParameter);
void main()
{
    HANDLE hThread1;
    hThread1=CreateThread(NULL,0,Fun1Proc,NULL,0,NULL);
    CloseHandle(hThread1);
    while(index++<1000)
    {
        count<<"main thread is running"<<endl;
    }
    Sleep(10);
}
//线程一的入口函数
DWORD WINAPI Fun1Proc(LPVOID lpParameter)
{
    while(index++<1000)
    {
        count<<"thread1 is running"<<endl;
    }
    return 0;
}

//这是index是一个全局变量,用来控制循环的次数。运行结果如图。先是主线程运行一段时间,当时间片到期时,线程一开始运行,为线程一分配一个时间片;线程一时间片到期时,就又开始运行主线程。
在这里插入图片描述

15.3线程同步

15.3.1火车站售票系统模拟程序

#include<windows.h>
#include<iostream.h>
DWORD WINAPI Fun1Proc(LPVOID lpParameter);
DWORD WINAPI Fun2Proc(LPVOID lpParameter);
int index=0;
int tickets=100;
void main()
{
    HANDLE hThread1;
    HANDLE hThread2;
    //创建线程
    hThread1=CreateThread(NULL,0,FunProc1,NULL,0,NULL);
    hThread2=CreateThread(NULL,0,FunProc2,NULL,0,NULL);
    CloseHandle(hThread1);
    CloseHandle(hThread2);
    Sleep(4000);//让主线程睡四秒,系统给线程1和线程2分配时间片运行
}
//线程1的入口函数
DWORD WINAPI Fun1Proc(LPVOID lpParameter)
{
    while(TRUE)
    {
        if(tickets>0)
        {
            cout<<"thread1 sell ticket:"<<tickets--<<endl;
        }
        else
        {
            break;
        }
    }
    return 0;
}
//线程2的入口函数
DWORD WINAPI Fun2Proc(LPVOID lpParameter)
{
    while(TRUE)
    {
        if(tickets>0)
        {
            cout<<"thread2 sell ticket:"<<tickets--<<endl;
        }
        else
        {
            break;
        }
    }
    return 0;
}
//运行结果如图。

在这里插入图片描述

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

身影王座

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值