windows多线程编程

进程共同实现某个任务或者共享计算机资源, 它们之间存在两种关系:

1.同步关系, 指为了完成任务的进程之间, 因为需要在某些位置协调它们的执行顺序而等待, 传递消息产生的制约关系.

2.互斥关系, 进程间因相互竞争使用独占型资源所产生的制约关系, 如一个进程使用打印机,另一个进程必须等待它使用完后才可使用.

临界资源: 一次仅允许一个进程使(必须互斥使用)的资源, 如独占型硬件资源.....

临界段: 指各进程必须互斥执行的程序段, 该程序段实施对临界资源的操作.

关键区对象为:CRITICAL_SECTION 当某个线程进入关键区之后,其他线程将阻塞等待,直到该线程释放关键区的拥有权.

#include <windows.h>
#include <stdio.h>

static int number=10;
CRITICAL_SECTION CriticalSection;

DWORD WINAPI ThreadOne(LPVOID lpParameter)
{
    printf("窗口1售票开始:\n");
    while(1)
    {
         EnterCriticalSection(&CriticalSection);
         if(number>0)
         {
             printf("窗口1售出第%d张票...\n",number);
             number--;
             Sleep(1000);
         }
         LeaveCriticalSection(&CriticalSection);
         Sleep(100);
    }
    return 0;
}
 DWORD WINAPI ThreadTwo(LPVOID lpParameter)
 {
     printf("窗口2售票开始:\n");
     while(1)
     {
         EnterCriticalSection(&CriticalSection);
         if(number>0)
         {
             printf("窗口2售出第%d张票...\n",number);
             Sleep(1000);
             number--;
         }
         LeaveCriticalSection(&CriticalSection);
         Sleep(100);
     }
     return 0;
 }

 int main()
 {
     HANDLE HOne,HTwo;
     InitializeCriticalSection(&CriticalSection);
     printf("***********************vpoet******************\n");
     HOne=CreateThread(NULL,0,ThreadOne,NULL,0,NULL);
     HTwo=CreateThread(NULL,0,ThreadTwo,NULL,0,NULL);
     CloseHandle(HOne);
     CloseHandle(HTwo);
     while(TRUE)
     {
         if(number==0)
         {
             printf("不好意思,票卖完了!\n");
             DeleteCriticalSection(&CriticalSection);
             return 0;
         }
         else
         {
             continue;
         }
     }

     return 0;
 }

信号量机制: 由信号量和P操作,V操作两部分组成, 可以解决互斥与同步问题. 信号量(s)为一个整型变量, 只能被两个标准原语访问, 分别记为P操作和V操作.

定义如下:

 P(s){
     while s <= 0
         ; //空操作
          s = s - 1;
 }

V(s){
    s =s + 1;
}

信号量可以解决n个进程的临界段问题, n个进程共享一个公共变量mutex, 其初值为 1 , 任意一个进程Pi的结果如下:

do{
    P(mutex);
    critical secition
    V(mutex);
    non critical secition
}while(1);

信号量也可以解决进程间同步问题.

利用信号量解决线程同步问题

 #include <windows.h>
 #include <stdio.h>

 static int number=10;
 HANDLE Sem;

 DWORD WINAPI ThreadOne(LPVOID lpParameter)
 {
     printf("窗口1售票开始:\n");
     while(1)
     {
          // 信号量 >  0, 减去 1
         WaitForSingleObject(Sem,INFINITE);
         if(number>0)
         {
             printf("窗口1售出第%d张票...\n",number);
             number--;
             Sleep(1000);
         }
         // 信号量  < 0 , 加上 1
         ReleaseSemaphore(Sem,1,NULL);
         Sleep(100);
     }
     return 0;
 }
 DWORD WINAPI ThreadTwo(LPVOID lpParameter)
 {
     printf("窗口2售票开始:\n");
     while(1)
     {
         WaitForSingleObject(Sem,INFINITE);
         if(number>0)
         {
             printf("窗口2售出第%d张票...\n",number);
             Sleep(1000);
             number--;
         }
         ReleaseSemaphore(Sem,1,NULL);
         Sleep(100);
     }
     return 0;
 }

 int main()
 {
     HANDLE HOne,HTwo;

     printf("***********************vpoet******************\n");
     HOne=CreateThread(NULL,0,ThreadOne,NULL,0,NULL);
     HTwo=CreateThread(NULL,0,ThreadTwo,NULL,0,NULL);
     //创建信号量, 初始为 1 , 最大计数为 1
     Sem=CreateSemaphore(NULL,1,1,NULL);
     CloseHandle(HOne);
     CloseHandle(HTwo);
     while(TRUE)
     {
         if(number==0)
         {
             printf("不好意思,票卖完了!\n");
             CloseHandle(Sem);
             return 0;
         }
         else
         {
             continue;
         }
     }

     return 0;
 }

信号量的具体实现:与进程调度相结合, 消除忙等待现象.

基本思想:

在P操作循环等待的地方介入放弃处理机, 进入等待对了动作.

在V操作时, 从等待队列中摘取进程变为就绪.

信号量定义

typedef struct{
       int:value;  一个数值型变量
       struct process *L;一个PCB队列
       } Semaphore
Semaphore S;

P操作

   P(S):      S.Value=S.value-1;
              if S.value<0 then 保存现场,
              将本进程挂入S.L队列,等待重新调度

请求分配一个S代表的资源, 若S.value < 0, 代表系统无此资源, 申请者阻塞.

V操作

   V(S):          S.value:=value+1
                  if S.value≤0 then 从S.L队列
                  取一进程,挂入就绪队列。

进程释放一个S代表的资源, 若S.value <= 0, 表示尚有进程在等待S而被阻塞, 所有要唤醒其一.

管程

共享资源用共享数据结构表示, 把分散的对共享资源的临界段集中于管程中, 管程中的临界程序一次只允许一个进程调用.

主要构成:共享数据结构,  对共享数据结构操作的一组函数, 数据结构的初始化程序.

时间: 2024-10-29 02:53:45

windows多线程编程的相关文章

Windows多线程编程总结

Windows 多线程编程总结 keyword:多线程 线程同步 线程池 内核对象 1 内核对象 1 .1 内核对象的概念 内核对象是内核分配的一个内存块,这样的内存块是一个数据结构,表示内核对象的各种特征.而且仅仅能由内核来訪问.应用程序若须要訪问内核对象,须要通过操作系统提供的函数来进行,不能直接訪问内核对象( Windows 从安全性方面来考虑的). 内核对象通过 Create* 来创建,返回一个用于标识内核对象的句柄,这些句柄 (而不是内核对象)可在创建进程范围内使用,不可以被传递到其它

Windows多线程编程及常见问题

提要: Windows 多线程Helloworld 以Windows代码为例,分析多线程编程中易出现的问题 Windows多线程的Helloworld: 笔者写过Java多线程的程序(实现Runnable接口,利用Thread类执行),也写过Linux多线程程序(利用pthread).最近由于另有需要使用Windows多线程,由于Windows API历来难用,特此记录,以作备忘. Helloworld源代码如下: 1 #include <stdio.h> 2 #include <win

【APUE】关于windows多线程编程的学习笔记

保证在某一时刻只有一个线程对数据进行操作的基本方法: (1)关中断:通过关闭时钟中断来停止线程调度(不现实) (2)数学互斥方法:Peterson算法 bakery算法 (3)操作系统提供的互斥方法:临界区.互斥量.信号量等(windows) (4)cpu原子操作:把一些常用的指令设计成了原子指令,在windows上面也被称为原子锁 [APUE]关于windows多线程编程的学习笔记

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

源出处:http://www.cnblogs.com/TenosDoIt/archive/2013/04/15/3022036.html CreateThread:Windows的API函数(SDK函数的标准形式,直截了当的创建方式,任何场合都可以使用),提供操作系统级别的创建线程的操作,且仅限于工作者线程 beginthread beginthreadex:MS对C Runtime库的扩展SDK函数,首先针对C Runtime库做了一些初始化的工作,以保证C Runtime库工作正常,然后,调

Windows下多线程编程(一)

前言 熟练掌握Windows下的多线程编程,能够让我们编写出更规范多线程代码,避免不要的异常.Windows下的多线程编程非常复杂,但是了解一些常用的特性,已经能够满足我们普通多线程对性能及其他要求. 进程与线程 1. 进程的概念 进程就是正在运行的程序.主要包括两部分: • 一个是操作系统用来管理进程的内核对象.内核对象也是系统用来存放关于进程的统计信息的地方. • 另一个是地址空间,它包含所有可执行模块或 D L L模块的代码和数据.它还包含动态内 2. 线程的概念 线程就是描述进程的一条执

Windows下多线程编程

熟练掌握Windows下的多线程编程,能够让我们编写出更规范多线程代码,避免不要的异常.Windows下的多线程编程非常复杂,但是了解一些常用的特性,已经能够满足我们普通多线程对性能及其他要求. 进程与线程 1. 进程的概念 进程就是正在运行的程序.主要包括两部分: ? 一个是操作系统用来管理 ... bbs.chinaacc.com/forum-2-3/topic-5662298.html bbs.chinaacc.com/forum-2-3/topic-5662294.html bbs.ch

C语言使用pthread多线程编程(windows系统)二

我们进行多线程编程,可以有多种选择,可以使用WindowsAPI,如果你在使用GTK,也可以使用GTK实现了的线程库,如果你想让你的程序有更多的移植性你最好是选择POSIX中的Pthread函数库,我的程序是在Linux下写的,所以我使用了Pthread库(是不是很伤心,我知道有不少人期待的是WindowsAPI的,好吧,有机会以后再讲那个,现在先把这一系列专题写完 ^_^)如果你用的是LINUX/UNIX/MacOSX,那么我们已经可以开始了,如果你用的是WINDOWS,那么你需要从网站上下载

【转】Windows的多线程编程,C/C++

在Windows的多线程编程中,创建线程的函数主要有CreateThread和_beginthread(及_beginthreadex). CreateThread 和 ExitThread    使用API函数CreateThread创建线程时,其中的线程函数原型:  DWORD WINAPI ThreadProc(LPVOID lpParameter);在线程函数返回后,其返回值用作调用ExitThread函数的参数(由系统隐式调用).可以使用GetExitCodeThread函数获得该线程

【转】《windows核心编程》读书笔记

这篇笔记是我在读<Windows核心编程>第5版时做的记录和总结(部分章节是第4版的书),没有摘抄原句,包含了很多我个人的思考和对实现的推断,因此不少条款和Windows实际机制可能有出入,但应该是合理的.开头几章由于我追求简洁,往往是很多单独的字句,后面的内容更为连贯. 海量细节. 第1章    错误处理 1.         GetLastError返回的是最后的错误码,即更早的错误码可能被覆盖. 2.         GetLastError可能用于描述成功的原因(CreatEvent)