• 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售票开始:
    ");
        while(1)
        {
             EnterCriticalSection(&CriticalSection);  
             if(number>0)
             {
                 printf("窗口1售出第%d张票...
    ",number);
                 number--;
                 Sleep(1000);        
             }
             LeaveCriticalSection(&CriticalSection);
             Sleep(100);
        }
        return 0;
    }
     DWORD WINAPI ThreadTwo(LPVOID lpParameter)
     {
         printf("窗口2售票开始:
    ");
         while(1)
         {
             EnterCriticalSection(&CriticalSection);
             if(number>0)
             {
                 printf("窗口2售出第%d张票...
    ",number);
                 Sleep(1000);
                 number--;
             }
             LeaveCriticalSection(&CriticalSection);
             Sleep(100);
         }
         return 0;
     }
     
     
     int main()
     {
         HANDLE HOne,HTwo;
         InitializeCriticalSection(&CriticalSection);
         printf("***********************vpoet******************
    ");
         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("不好意思,票卖完了!
    ");
                 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售票开始:
    ");
         while(1)
         {
              // 信号量 >  0, 减去 1 
             WaitForSingleObject(Sem,INFINITE);
             if(number>0)
             {
                 printf("窗口1售出第%d张票...
    ",number);
                 number--;
                 Sleep(1000);        
             }
             // 信号量  < 0 , 加上 1 
             ReleaseSemaphore(Sem,1,NULL);
             Sleep(100);
         }
         return 0;
     }
     DWORD WINAPI ThreadTwo(LPVOID lpParameter)
     {
         printf("窗口2售票开始:
    ");
         while(1)
         {
             WaitForSingleObject(Sem,INFINITE);
             if(number>0)
             {
                 printf("窗口2售出第%d张票...
    ",number);
                 Sleep(1000);
                 number--;
             }
             ReleaseSemaphore(Sem,1,NULL);
             Sleep(100);
         }
         return 0;
     }
     
     
     int main()
     {
         HANDLE HOne,HTwo;
         
         printf("***********************vpoet******************
    ");
         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("不好意思,票卖完了!
    ");
                 CloseHandle(Sem);
                 return 0;
             }
             else
             {
                 continue;
             }    
         }
         
         return 0;
     }
     
     
    View Code

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

    基本思想:

    在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而被阻塞, 所有要唤醒其一. 

    管程

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

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

    互斥对象实现线程同步

    互斥对象的所有权轮换给两个线程

    #include <windows.h>
    #include <stdio.h>
    
    static int number=10;
    HANDLE Mutex;
    
    DWORD WINAPI ThreadOne(LPVOID lpParameter)
    {
        while(1)
        {
            //等待互斥对象有多有权才返回 
            WaitForSingleObject(Mutex,INFINITE);  
            if(number>0)
            {
                printf("窗口1售出第%d张票...
    ",number);
                number--;
                Sleep(1000);        
            }
            //释放互斥对象所有权 
            ReleaseMutex(Mutex);    
        }
        return 0;
    }
    DWORD WINAPI ThreadTwo(LPVOID lpParameter)
    {
        while(1)
        {
            WaitForSingleObject(Mutex,INFINITE);
            if(number>0)
            {
                printf("窗口2售出第%d张票...
    ",number);
                Sleep(1000);
                number--;
            }
            ReleaseMutex(Mutex);
        }
        return 0;
    }
    
    
    int main()
    {
        HANDLE HOne,HTwo;
        Mutex=CreateMutex(NULL,FALSE,NULL);
        printf("***********************vpoet******************
    ");
        HOne=CreateThread(NULL,0,ThreadOne,NULL,0,NULL);
        printf("窗口1售票开始:
    ");
        HTwo=CreateThread(NULL,0,ThreadTwo,NULL,0,NULL);
        printf("窗口2售票开始:
    ");
        CloseHandle(HOne);
        CloseHandle(HTwo);
        while(TRUE)
        {
            if(number==0)
            {
                printf("不好意思,票卖完了!
    ");
                CloseHandle(Mutex);
                return 0;
            }
            else
            {
                continue;
            }    
        }
    
        return 0;
    }
  • 相关阅读:
    我们如何监视所有 Spring Boot 微服务?
    如何使用 Spring Boot 实现异常处理?
    如何使用 Spring Boot 实现分页和排序?
    如何集成 Spring Boot 和 ActiveMQ?
    如何实现 Spring Boot 应用程序的安全性?
    Spring Boot 中的监视器是什么?
    如何重新加载 Spring Boot 上的更改,而无需重新启动服务器?
    Spring 和 SpringBoot 有什么不同?
    Spring Boot 有哪些优点?
    如何在不使用BasePACKAGE过滤器的情况下排除程序包?
  • 原文地址:https://www.cnblogs.com/tanxing/p/6101034.html
Copyright © 2020-2023  润新知