zoukankan      html  css  js  c++  java
  • 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;
    }
  • 相关阅读:
    zbb20181207 springboot @ConfigurationProperties使用
    zbb20181206 logback,lombok 默认日志logback配置解析
    Spring Boot (8) 全局异常处理
    Spring Boot (7) JdbcTemplate访问数据库
    Spring Boot (6) Spring Data JPA
    Spring Boot (4) 静态页面和Thymeleaf模板
    Spring Boot (3) 热部署devtools
    Spring Boot (2) Restful风格接口
    Spring Boot (1) 构建第一个Spring Boot工程
    idea使用maven搭建ssm框架实现登陆商品增删改查
  • 原文地址:https://www.cnblogs.com/tanxing/p/6101034.html
Copyright © 2011-2022 走看看