谭兄

导航

 

 

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

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;
 }
 
 
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张票...\n",number);
            number--;
            Sleep(1000);        
        }
        //释放互斥对象所有权 
        ReleaseMutex(Mutex);    
    }
    return 0;
}
DWORD WINAPI ThreadTwo(LPVOID lpParameter)
{
    while(1)
    {
        WaitForSingleObject(Mutex,INFINITE);
        if(number>0)
        {
            printf("窗口2售出第%d张票...\n",number);
            Sleep(1000);
            number--;
        }
        ReleaseMutex(Mutex);
    }
    return 0;
}


int main()
{
    HANDLE HOne,HTwo;
    Mutex=CreateMutex(NULL,FALSE,NULL);
    printf("***********************vpoet******************\n");
    HOne=CreateThread(NULL,0,ThreadOne,NULL,0,NULL);
    printf("窗口1售票开始:\n");
    HTwo=CreateThread(NULL,0,ThreadTwo,NULL,0,NULL);
    printf("窗口2售票开始:\n");
    CloseHandle(HOne);
    CloseHandle(HTwo);
    while(TRUE)
    {
        if(number==0)
        {
            printf("不好意思,票卖完了!\n");
            CloseHandle(Mutex);
            return 0;
        }
        else
        {
            continue;
        }    
    }

    return 0;
}

 

posted on 2016-11-25 21:41  谭兄  阅读(10986)  评论(0编辑  收藏  举报