zoukankan      html  css  js  c++  java
  • API 练习 第一篇

    练习API  
    CreateSemaphore
    CreateEvent
    ReleaseSemap
    WaitForSingleObject 
    CloseHandle
    InitializeCriticalSection
    EnterCriticalSection
    LeaveCriticalSection
    DeleteCriticalSection
    例子:读者与写者,有一位写者与三位读者,要求当三位读者都读操作完成时写者才能开始写操作,写的过程中不能有任何读者进行读操作。用信号量解决问题
    代码如下:

    // ReaderAndWriter.cpp : 定义控制台应用程序的入口点。
    //

    #include "stdafx.h"
    #include <Windows.h>
    #include <stdio.h>

    int gBook = 0;
    CRITICAL_SECTION cs;

    //线程句柄
    HANDLE hThread[4];

    //线程体
    DWORD WINAPI threadWrite(void *param);
    DWORD WINAPI threadRead1(void *param);
    DWORD WINAPI threadRead2(void *param);
    DWORD WINAPI threadRead3(void *param);

    //信号量句柄
    HANDLE hWriteSM;
    HANDLE hRead1SM;
    HANDLE hRead2SM;
    HANDLE hRead3SM;

    //线程退出事件
    HANDLE hEventWriteExit;
    HANDLE hEventRead1Exit;
    HANDLE hEventRead2Exit;
    HANDLE hEventRead3Exit;

    /********************************************
    程序说明:
    一个写线程与三个读线程共同访问gBook,要求当三
    个读线程都读完后,写线程才开始写gBook。
    主线程等待6秒后通知退出事件,清理资源,结束程序
    *********************************************/
    int _tmain(int argc, _TCHAR* argv[])
    {
            //初始化临界区
    	InitializeCriticalSection(&cs);
            //线程退出事件
    	hEventWriteExit = CreateEvent(NULL, false, false, NULL);
    	hEventRead1Exit = CreateEvent(NULL, false, false, NULL);
    	hEventRead2Exit = CreateEvent(NULL, false, false, NULL);
    	hEventRead3Exit = CreateEvent(NULL, false, false, NULL);
            //创建读者写者信号量
    	hWriteSM = CreateSemaphore(NULL, 0, 3, NULL);//写信号量初始为unsignal ,可知先进行的是读操作
    	hRead1SM = CreateSemaphore(NULL, 1, 1, NULL);//读信号量初始为signal,
            hRead2SM = CreateSemaphore(NULL, 1, 1, NULL);//读信号量初始为signal,
    	hRead3SM = CreateSemaphore(NULL, 1, 1, NULL);//读信号量初始为signal,
            //创建四个线程
    	hThread[0] = CreateThread(NULL, 0, threadWrite, NULL, 0, NULL);
    	hThread[1] = CreateThread(NULL, 0, threadRead1, NULL, 0, NULL);
    	hThread[2] = CreateThread(NULL, 0, threadRead2, NULL, 0, NULL);
    	hThread[3] = CreateThread(NULL, 0, threadRead3, NULL, 0, NULL);
            //等待线程执行6秒
    	Sleep(1000 * 6);
            //发出通知线程结束事件
    	SetEvent(hEventWriteExit);
    	SetEvent(hEventRead1Exit);
    	SetEvent(hEventRead2Exit);
    	SetEvent(hEventRead3Exit);
            //等待四个线程都结束
    	WaitForMultipleObjects(4, hThread, true, INFINITE);
           //关闭句柄,清理资源
    	CloseHandle(hEventWriteExit);
    	CloseHandle(hEventRead1Exit);
    	CloseHandle(hEventRead2Exit);
    	CloseHandle(hEventRead3Exit);
    
    	CloseHandle(hWriteSM);
    	CloseHandle(hRead1SM);
    	CloseHandle(hRead2SM);
    	CloseHandle(hRead3SM);
    
    	for (int i = 0; i < 4; i ++)
    		CloseHandle(hThread[i]);
    
    	DeleteCriticalSection(&cs);
    
    	printf("	 main end 
    ");
    
    	return 0;
    }
    
    DWORD WINAPI threadWrite(void *param)
    {
    	while(1)
    	{
    		DWORD dwWait = WaitForSingleObject(hEventWriteExit, 10);
    		if (WAIT_TIMEOUT != dwWait)
    		{
    			//接收到退出事件后先把资源归还,避免造成死锁
    			ReleaseSemaphore(hRead1SM, 1, NULL);
    			ReleaseSemaphore(hRead2SM, 1, NULL);
    			ReleaseSemaphore(hRead3SM, 1, NULL);
    			break;
    		}
    		WaitForSingleObject(hWriteSM, INFINITE);
    		WaitForSingleObject(hWriteSM, INFINITE);
    		WaitForSingleObject(hWriteSM, INFINITE);
    
    		EnterCriticalSection(&cs);
    		gBook ++;
    		printf(" 
     Write Process end:%d 
    ", gBook);
    		LeaveCriticalSection(&cs);
    
    		ReleaseSemaphore(hRead1SM, 1, NULL);
    		ReleaseSemaphore(hRead2SM, 1, NULL);
    		ReleaseSemaphore(hRead3SM, 1, NULL);
    
    		Sleep(1000);
    	}
    
    	printf("
    ******************writer Terminate 
    ");
    	return 0;
    }
    
    DWORD WINAPI threadRead1(void *param)
    {
    	while(1)
    	{
    		DWORD dwWait = WaitForSingleObject(hEventRead1Exit, 10);
    		if (WAIT_TIMEOUT != dwWait)
    		{
    			//接收到退出事件后先把资源归还,避免造成死锁
    			ReleaseSemaphore(hWriteSM, 1, NULL);
    			break;
    		}
    		WaitForSingleObject(hRead1SM, INFINITE);
    		EnterCriticalSection(&cs);
    		printf("reader1 process end %d 	", gBook);
    		LeaveCriticalSection(&cs);
    
    		ReleaseSemaphore(hWriteSM, 1, NULL);
    
    		Sleep(100 * 1);
    	}
    
    	printf("
    ******************read1 Terminate 
    ");
    	return 0;
    }
    
    DWORD WINAPI threadRead2(void *param)
    {
    	while(1)
    	{
    		DWORD dwWait = WaitForSingleObject(hEventRead2Exit, 10);
    		if (WAIT_TIMEOUT != dwWait)
    		{
    			//接收到退出事件后先把资源归还,避免造成死锁
    			ReleaseSemaphore(hWriteSM, 1, NULL);
    			break;
    		}
    		WaitForSingleObject(hRead2SM, INFINITE);
    		EnterCriticalSection(&cs);
    		printf("reader2 process end %d 	", gBook);
    		LeaveCriticalSection(&cs);
    
    		ReleaseSemaphore(hWriteSM, 1, NULL);
    
    		Sleep(1000 * 0.5);
    	}
    
    	printf("
    ******************reader2 Terminate 
    ");
    	return 0;
    }
    DWORD WINAPI threadRead3(void *param)
    {
    	while(1)
    	{
    		//接收到退出事件后先把资源归还,避免造成死锁
    		DWORD dwWait = WaitForSingleObject(hEventRead3Exit, 10);
    		if (WAIT_TIMEOUT != dwWait)
    		{
    			ReleaseSemaphore(hWriteSM, 1, NULL);
    			break;
    		}
    		WaitForSingleObject(hRead3SM, INFINITE);
    
    		EnterCriticalSection(&cs);
    		printf("reader3 process end %d 	", gBook);
    		LeaveCriticalSection(&cs);
    
    		ReleaseSemaphore(hWriteSM, 1, NULL);
    
    		Sleep(1000 * 1);
    	}
    
    	printf("
    ******************reader3 Terminate 
    ");
    	return 0;
    }
    
     

    结果如下:

    API 练习 第一天 - 快乐男孩 - work labor and play
    说明:三个读线程读完后,写线程开始写操作,克制结果正确。每次执行时可能结果有所不同,但只有terminate那几行有差异,前面的都相同,原因是当主线程发出通知结束线程事件后,各线程突然跳出,而且无顺序的跳出,线程中等待的时间也有差异,导致这样的结果。

     

  • 相关阅读:
    测试的基本方法
    一些基本常用的正则表达式
    MySQL和Oracle的区别与不同
    Ubuntu中使用python3中的venv创建虚拟环境
    在Ubuntu中搭建Python3的虚拟环境并开始django项目
    Django中的图片加载不出来解决方式记录
    在django中进行后台管理时插入外键数据时不显示值的问题
    Django2.2连接mysql数据库出现django.core.exceptions.ImproperlyConfigured: mysqlclient 1.3.3 or newer is required; you have 0.7.11.None问题
    在Ubuntu中安装了MongoDB后无法启动mongod的问题
    PostgreSQL练习3
  • 原文地址:https://www.cnblogs.com/priarieNew/p/9753436.html
Copyright © 2011-2022 走看看