我是靠谱客的博主 精明翅膀,最近开发中收集的这篇文章主要介绍多线程代码编写,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

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

#include "stdafx.h"
#include <windows.h>
#include<iostream>
#include <luabind/luabind.hpp>
#include <luabind/lua_include.hpp>
#include<string.h>
using namespace std;


#include <stdio.h>
#include <process.h>
#include "conio.h"


extern "C" {
	#include <lua.h>
	#include <lualib.h>
	#include <lauxlib.h>
};

//#include<lua.hpp>
//#include<luabind/luabind.hpp>
#include <luabind/function.hpp>//注册函数
using namespace luabind;
static int CppFunctionName(lua_State *L)
{
	// 向函数栈中压入2个值  
	lua_pushnumber(L, 10);  
	lua_pushstring(L, "dugaode hello world");  

	/* 返回值个数,2表示返回2个参数 */
	return 2;  
}

static struct StudentTag
{
	char *strName; // 学生姓名
	char *strNum; // 学号
	int iSex; // 学生性别
	int iAge; // 学生年龄
};

class dugaodaInfo
{
public:
	dugaodaInfo();
	~dugaodaInfo();
	inline void print() { cout << " functionresult " << mm << endl; };
private:
	int mm; 
};

dugaodaInfo::dugaodaInfo()
{
	mm = 1;
}

dugaodaInfo::~dugaodaInfo()
{
}
//lua 中通过调用这个接口来得到 pStudent指针
static int Student(lua_State *L)
{
	size_t iBytes = sizeof(struct StudentTag);
	struct StudentTag *pStudent;
	pStudent = (struct StudentTag *)lua_newuserdata(L, iBytes);

	return 1; // 新的userdata已经在栈上了
}

static int GetName(lua_State *L)
{
	struct StudentTag *pStudent = (struct StudentTag *)lua_touserdata(L, 1);
	luaL_argcheck(L, pStudent != NULL, 1, "Wrong Parameter");
	lua_pushstring(L, pStudent->strName);
	return 1;
}

static int SetName(lua_State *L)
{
	// 第一个参数是userdata
	struct StudentTag *pStudent = (struct StudentTag *)lua_touserdata(L, 1);
	luaL_argcheck(L, pStudent != NULL, 1, "Wrong Parameter");

	// 第二个参数是一个字符串
	const char *pName = luaL_checkstring(L, 2);//检查第2个参数是不是string,并返回参数值
	luaL_argcheck(L, pName != NULL && pName != "", 2, "Wrong Parameter");

	pStudent->strName = (char *)pName;
	return 0;
}

static int GetAge(lua_State *L)
{
	struct StudentTag *pStudent = (struct StudentTag *)lua_touserdata(L, 1);
	luaL_argcheck(L, pStudent != NULL, 1, "Wrong Parameter");
	lua_pushinteger(L, pStudent->iAge);
	return 1;
}
static int SetAge(lua_State *L)
{
	struct StudentTag *pStudent = (struct StudentTag *)lua_touserdata(L, 1);
	luaL_argcheck(L, pStudent != NULL, 1, "Wrong Parameter");

	int iAge = luaL_checkinteger(L, 2);
	luaL_argcheck(L, iAge >= 6 && iAge <= 100, 2, "Wrong Parameter");
	pStudent->iAge = iAge;
	return 0;
}
static int GetSex(lua_State *L)
{
	// 这里由你来补充
	struct StudentTag *pStudent = (struct StudentTag *)lua_touserdata(L, 1);
	luaL_argcheck(L, pStudent != NULL, 1, "get wrong arg from lua");
	lua_pushnumber(L, pStudent->iSex);//通过C++操作把数据放入到堆栈中,  1表示男 2表示女
	return 1;
}

static int SetSex(lua_State *L)
{
	// 这里由你来补充
	struct StudentTag *pStudent = (struct StudentTag *)lua_touserdata(L, 1);
	luaL_argcheck(L, pStudent != NULL, 1, "get wrong arg from lua");

	int iSex = luaL_checkinteger(L, 2);
	luaL_argcheck(L, iSex == 1 || iSex == 2, 2, "get wrong arg from lua");
	pStudent->iSex = iSex;

	return 0;
}

static int GetNum(lua_State *L)
{
	// 这里由你来补充






	return 1;
}

static int SetNum(lua_State *L)
{
	// 这里由你来补充




	return 0;
}

static struct luaL_reg arrayFunc[] =
{
	{"new", Student},//注册成为Student的接口
	{"getName", GetName},
	{"setName", SetName},
	{"getAge", GetAge},
	{"setAge", SetAge},
	{"getSex", GetSex},
	{"setSex", SetSex},
	{"getNum", GetNum},
	{"setNum", SetNum},
	{NULL, NULL}
};

int luaopen_userdatademo1(lua_State *L)
{
	luaL_register(L, "Student", arrayFunc);
	luaL_dofile(L, "main.lua");
	return 1;
}



int luaopen_lightuserdatademo(lua_State *L)
{

	static char key = 'key';
	lua_pushlightuserdata(L, (void *)&key);
	lua_pushstring(L, "JellyThink");
	lua_settable(L, LUA_REGISTRYINDEX);


	//luaL_register(L, "Student", arrayFunc);
	//luaL_dofile(L, "main.lua");
	return 1;
}

//子线程函数
DWORD WINAPI ThreadFun(LPVOID pM)
{
	printf("子线程的线程ID号为:%d", GetCurrentThreadId());
	printf("子线程输出  杜高达");
	return 0;
}

int nThreadAmount = 0;
unsigned int WINAPI	ThreadFun2(LPVOID pM)
{
	nThreadAmount++;
	printf("%dn", nThreadAmount);
	printf("子线程的线程ID号为:%dn", GetCurrentThreadId());
	printf("子线程输出  杜高达n");
	return 0;
}

volatile long g_nLoginCount;//登录次数
unsigned int __stdcall Fun(void *pPM);//线程函数
const int THREAD_NUM = 100;//启动线程数
unsigned int __stdcall ThreadFun3(void *pPM)
{
	Sleep(100);
	g_nLoginCount++;
	Sleep(50);
	return 0;
}


unsigned int __stdcall ThreadFun4(void *pPM)
{
	Sleep(100);
	InterlockedIncrement((LPLONG)&g_nLoginCount);
	Sleep(50);
	return 0;
}

long g_nNum;
const int THREAD_NUM5 = 10;//启动线程数
unsigned int __stdcall ThreadFun5(void *pPM);//线程函数

unsigned int __stdcall ThreadFun5(void *pPM)
{
	int nThreadNum = *(int *)pPM;//子线程获取参数
	Sleep(50);
	g_nNum++;
	Sleep(0);
	printf("线程编号为%d  全局资源值为%dn", nThreadNum, g_nNum);
	return 0;
}


long g_nResAmount;
const int THREAD_NUM6 = 10;
CRITICAL_SECTION g_csThreadParameter, g_csThreadCode;
unsigned int __stdcall ThreadFun6(void *pPM);
unsigned int __stdcall ThreadFun6(void *pPM)
{
	int nThreadNum = *(int *)pPM;
	LeaveCriticalSection(&g_csThreadParameter);//离开子线程序号关键区域
	Sleep(50);
	EnterCriticalSection(&g_csThreadCode);//进入各子线程互斥区域 
	g_nResAmount++;
	Sleep(0);
	printf("线程编号为%d  全局资源值为%dn", nThreadNum, g_nResAmount);
	LeaveCriticalSection(&g_csThreadCode);

	return 0;
}

long g_nResNum7;
unsigned int __stdcall ThreadFun7(void *pPM);
const int THREAD_NUM7 = 10;
//事件与关键段
HANDLE g_hThreadEvent;
CRITICAL_SECTION g_csThreadCode7;
unsigned int __stdcall ThreadFun7(void *pPM)
{
	int nThreadAmount = *(int *)pPM;
	SetEvent(g_hThreadEvent);//触发事件
	Sleep(50);

	EnterCriticalSection(&g_csThreadCode7);
	g_nResNum7++;
	Sleep(0);
	printf("线程编号为%d  全局资源值为%dn", nThreadAmount, g_nResNum7);

	LeaveCriticalSection(&g_csThreadCode7);
	return 0;
}


HANDLE g_hThreadEvent8;

//快线程
unsigned int __stdcall FastThreadFun(void *pPm)
{
	Sleep(10);//用这个来保证各线程调用等待函数的次序有一定的随机性
	printf("%s 启动n", (PSTR)pPm);
	WaitForSingleObject(g_hThreadEvent8, INFINITE);
	printf("%s 等到事件被触发 顺利结束n", (PSTR)pPm);
	return 0;
}

//慢线程
unsigned int __stdcall SlowThreadFun(void *pPm)
{
	Sleep(100);
	printf("%s 启动n", (PSTR)pPm);
	WaitForSingleObject(g_hThreadEvent8, INFINITE);
	printf("%s 等到事件被触发 顺利结束n", (PSTR)pPm);
	return 0;
}


long g_nResAmount9;
unsigned int __stdcall ThreadFun9(void *pPm);
const int THREAD_NUM9 = 10;
HANDLE g_hThreadParameter9;
CRITICAL_SECTION g_csThreadCode9;
unsigned int __stdcall ThreadFun9(void *pPm)
{
	int nThreadNum = *(int *)pPm;
	ReleaseMutex(g_hThreadParameter9);//触发互斥量

	Sleep(50);

	EnterCriticalSection(&g_csThreadCode9);
	g_nResAmount9++;
	Sleep(0);
	printf("线程编号为%d  全局资源值为%dn", nThreadNum, g_nResAmount9); 
	LeaveCriticalSection(&g_csThreadCode9);
	return 0;
}

const char MUTEX_NAME[] = "Mutex_MoreWindows";


long g_nResNum10;
unsigned int __stdcall ThreadFun10(void *pPm);
const int THREAD_NUM10 = 10;
HANDLE				g_hThreadParameter10;
CRITICAL_SECTION	g_csThreadCode10;
unsigned int __stdcall ThreadFun10(void *pPm)
{
	int nThreadNum = *(int *)pPm;
	ReleaseSemaphore(g_hThreadParameter10, 1, NULL);//信号量++ 
	Sleep(0);

	EnterCriticalSection(&g_csThreadCode10);
	++g_nResNum10;
	Sleep(0);
	printf("线程编号%d,资源编号%dn", nThreadNum, g_nResNum10);

	LeaveCriticalSection(&g_csThreadCode10);
	return 0;
}

//设置控制台输出文字颜色
BOOL SetConsoleColor(WORD wAttributes)
{
	HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
	if (hConsole == INVALID_HANDLE_VALUE)
	{
		return FALSE;
	}
	return SetConsoleTextAttribute(hConsole, wAttributes);
}

//const int END_PRODUCE_NUMBER = 10;
//int g_nBuffer;//缓冲区
//CRITICAL_SECTION g_cs;
//HANDLE g_hEventBufferEmpty, g_hEventBufferFull;
//
生产者线程函数
//unsigned int __stdcall ProducerThreadFun(PVOID pM)
//{
//	for (int i = 1; i <= END_PRODUCE_NUMBER; i++)
//	{
//		//等待缓冲区为空
//		WaitForSingleObject(g_hEventBufferEmpty, INFINITE);
//		
//		//互斥的访问缓冲区
//		EnterCriticalSection(&g_cs);
//		g_nBuffer = i;
//		printf("生产者将数据%d放入缓冲区n", i);
//		LeaveCriticalSection(&g_cs);
//
//		//设置缓冲区有新数据
//		SetEvent(g_hEventBufferFull);
//	}
//	return 0;
//}
//
消费者线程函数
//unsigned int __stdcall ConsumerThreadFun(PVOID pM)
//{
//	volatile bool flag = true;
//	while (flag)
//	{
//		WaitForSingleObject(g_hEventBufferFull, INFINITE);
//
//		//互斥的访问缓冲区
//		EnterCriticalSection(&g_cs);
//		SetConsoleColor(FOREGROUND_RED);
//		printf("消费者得到的数据为%dn", g_nBuffer);
//		SetConsoleColor(FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE); 
//		if (g_nBuffer == END_PRODUCE_NUMBER)
//			flag = false;
//		LeaveCriticalSection(&g_cs);
//
//		SetEvent(g_hEventBufferEmpty);
//		Sleep(10);
//	}
//	return 0;
//}

//1生产者 2消费者 4缓冲区
const int END_PRODUCE_NUMBER2 = 10;
int g_nBuffer2[4];//缓冲区
int g_i, g_j;
CRITICAL_SECTION g_cs2;
HANDLE g_hSemaphoreBufferEmpty2, g_hSemaphoreBufferFull2;

//生产者线程函数
unsigned int __stdcall ProducerThreadFun2(PVOID pM)
{


	for (int i = 1; i <= END_PRODUCE_NUMBER2; i++)
	{
		//等待缓冲区为空
		WaitForSingleObject(g_hSemaphoreBufferEmpty2, INFINITE);

		//互斥的访问缓冲区
		EnterCriticalSection(&g_cs2);
		g_nBuffer2[g_i] = i;
		printf("生产者在缓冲池第%d个缓冲区中投放数据%dn", g_i, g_nBuffer2[g_i]);
		g_i = (g_i + 1 ) % 4;
		LeaveCriticalSection(&g_cs2);

		//通知消费者有新数据了
		ReleaseSemaphore(g_hSemaphoreBufferFull2, 1, NULL);
	}
	return 0;
}

//消费者线程函数
unsigned int __stdcall ConsumerThreadFun2(PVOID pM)
{
	while (true)
	{
		//等待非空的缓冲区出现 
		WaitForSingleObject(g_hSemaphoreBufferFull2, INFINITE);

		//互斥的访问缓冲区  
		EnterCriticalSection(&g_cs2); 
		//逻辑处理
		SetConsoleColor(FOREGROUND_GREEN);
		printf("消费者信息, 线程ID为%d, 从缓冲池%d取得数据%dn", GetCurrentThreadId(), g_j, g_nBuffer2[g_j]);
		SetConsoleColor(FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE);//设置会原来的控制台颜色
		if (g_nBuffer2[g_j] == END_PRODUCE_NUMBER2) //结束标记
		{
			LeaveCriticalSection(&g_cs2);
			//通知其它消费者有新数据了(结束标志)  
			ReleaseSemaphore(g_hSemaphoreBufferFull2, 1, NULL);  
			break;  
		}
		g_j = (g_j + 1) % 4;
		LeaveCriticalSection(&g_cs2);
		Sleep(50);
		ReleaseSemaphore(g_hSemaphoreBufferEmpty2, 1, NULL);
	}

	SetConsoleColor(FOREGROUND_RED);  
	printf("编号为%d的消费者收到通知,线程结束运行n", GetCurrentThreadId());  
	SetConsoleColor(FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE); 

	return 0;
}

const int READER_NUM = 5;//读者数量
CRITICAL_SECTION g_cs12, g_cs_writer_count;
HANDLE g_hEventWriter, g_hEventNoReader;
int g_nReaderCount;

//读者线程输出函数(变参函数的实现) 
void ReaderPrintf(char *pszFormat, ...)
{
	va_list pArgList;
	va_start(pArgList, pszFormat);
	EnterCriticalSection(&g_cs12);
	vfprintf(stdout, pszFormat, pArgList);
	LeaveCriticalSection(&g_cs12);
	va_end(pArgList);
}

//读者线程函数
unsigned int __stdcall ReaderThreadFun(PVOID pPm)
{
	ReaderPrintf("编号为%d的线程进入等待中.....n", GetCurrentThreadId());
	//等待写者完成。
	//等待g_hEventWriter线程函数中的内容调用结束,
	//在这个线程函数中只有设置g_event为有信号状态时才执行下面的EnterCriticalSection等内容
	WaitForSingleObject(g_hEventWriter, INFINITE);

	//读者个数增加
	EnterCriticalSection(&g_cs_writer_count);
	g_nReaderCount++;
	if (g_nReaderCount == 1)
	{
		//手动把g_hEventNoReader设置成为无信号状态
		ResetEvent(g_hEventNoReader);//把g_hEventNoReader设置成无信号状态,
	}
	LeaveCriticalSection(&g_cs_writer_count);

	//读取文件
	ReaderPrintf("编号为%d的线程开始读取文件.....n", GetCurrentThreadId());
	Sleep(rand() % 100);
	ReaderPrintf("编号为%d的线程读取文件结束.....n", GetCurrentThreadId());

	//读者个数减少
	EnterCriticalSection(&g_cs_writer_count);
	g_nReaderCount--;
	if (g_nReaderCount == 0)
	{
		//把g_hEventNoReader设置成为有信号状态
		SetEvent(g_hEventNoReader);//激活g_hEventNoReader事件,使得g_hEventNoReader变成有信号状态
	}
	LeaveCriticalSection(&g_cs_writer_count);

	return 0;
}

//写者线程输出函数
void WriterPrintf(char *pszStr)
{
	printf("写者输出n");
	EnterCriticalSection(&g_cs12);
	SetConsoleColor(FOREGROUND_BLUE);
	printf("		%sn", pszStr);
	SetConsoleColor(FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE);
	LeaveCriticalSection(&g_cs12);
}

//写者线程
unsigned int __stdcall WriterThreadFun(PVOID pPm)
{
	
	WriterPrintf("写者线程进入等待中......");
	//等待g_hEventNoReader事件触发接触从而进入到现在的线程函数中
	WaitForSingleObject(g_hEventNoReader, INFINITE);
	//标记写者正在写文件
	ResetEvent(g_hEventWriter);//把g_hEventWriter设置成为无信号状态
	WriterPrintf("写者开始写文件");
	Sleep(rand() % 100);
	WriterPrintf("写者写文件结束");

	//标记写者写文件结束
	SetEvent(g_hEventWriter);//写者操作结束,把g_hEventWriter设置成为无信号状态

	return 0;
}



const int READER_NUM14 = 6;
CRITICAL_SECTION	g_cs14;
SRWLOCK				g_srwLock;//读写锁
unsigned int __stdcall ReaderThreadFun14(PVOID pPm)
{

	ReaderPrintf("   编号为%d的读者进入等待中...n", GetCurrentThreadId());
	//读者申请读取文件
	AcquireSRWLockShared(&g_srwLock);

	//读取文件  
	ReaderPrintf("编号为%d的读者开始读取文件...n", GetCurrentThreadId());  
	Sleep(rand() % 100);  
	ReaderPrintf(" 编号为%d的读者结束读取文件n", GetCurrentThreadId());  

	//读者结束读取文件
	ReleaseSRWLockShared(&g_srwLock);
}


unsigned int __stdcall WriterThreadFun(PVOID pPm)
{
	WriterPrintf("写者线程进入等待中..."); 
	//写者申请写文件
	AcquireSRWLockExclusive(&g_srwLock);

	//写文件  
	WriterPrintf("  写者开始写文件.....");  
	Sleep(rand() % 100);  
	WriterPrintf("  写者结束写文件"); 

	//标记写者结束写文件
	ReleaseSRWLockExclusive(&g_srwLock);
}





int _tmain(int argc, _TCHAR* argv[])
{
	//lua_State *L = luaL_newstate();
	//if (L)
	//{
	//	luaL_openlibs(L);
	//}
	
	//int nRet = luaL_dofile(L, "test.lua");
	//if (nRet)
	//{
	//	cout<<"load file error"<<endl; 
	//}
//
//	//读取lua中的变量  
//	lua_getglobal(L,"myname");  
//	string str = lua_tostring(L, -1);  
//	cout << "myname = " << str.c_str() << endl;
//
//	//读取table
//	lua_getglobal(L, "myluatable");
//	lua_getfield(L, -1, "name");//lua_getfield读取table中字段的值,将字段的值读取到栈中;
//	if (lua_isstring(L, -1))
//	{
//		str = lua_tostring(L, -1);
//		cout << "myluatable   name = " << str.c_str() << endl;
//	}
//	//修改table中的值
//	lua_pushstring(L, "杜高达很帅!");
//	// 将这个值设置到table中(此时myluatable在栈的位置为2)
//	lua_setfield(L, 2, "name");
//
//	新建table
//	//lua_newtable(L);
//	//lua_pushstring(L, "xiaoxiaodu"); //将值压入栈 
//	//lua_setfield(L, -2, "name"); //将值设置到table中,并将Give me a girl friend 出栈 
//	//
//	检查myluatable中的值
//	//lua_getglobal(L, "myluatable");
//	//lua_getfield(L, -1, "name");//lua_getfield读取table中字段的值,将字段的值读取到栈中;
//	//if (lua_isstring(L, -1))
//	//{
//	//	str = lua_tostring(L, -1);
//	//	cout << "myluatable   name = " << str.c_str() << endl;
//	//}
//
	//C++调用lua中的读取函数
	//lua_getglobal(L, "dugaodafunction");
	//lua_pushnumber(L, 20);
	//lua_setglobal(L, "dde");
	//luaL_dofile(L, "tabletest.lua");
	//lua_pushnumber(L, 50);
	//nRet = lua_pcall(L, 2, 1, 0);
	//if (nRet)
	//{
	//	cout << " error " << endl;
	//}

	//if (lua_isnumber(L, -1))
	//{
	//	int functionresult = lua_tonumber(L, -1);
	//	cout << " functionresult " << functionresult << endl;
	//}
//
	//lua调用C++中的函数

	//lua_register(pL, "LuaFunctionName", CppFunctionName);

	//luaL_register(L, "Student", arrayFunc);//可以注册多个函数接口

	//luaopen_userdatademo1(L);
	//lua_rawget()
	//lua_ref()
	//int a = 1;
	lua_close(pL);

	//StudentTag aaa;
	//lua_pushlightuserdata(pL, (void *)&aaa);
	//lua_pushstring(pL , "JellyThink" );
	//lua_settable(pL , LUA_REGISTRYINDEX );
	//lua_pushcclosure()
	//lua_setglobal()

	操作lua中的table
	//lua_State* pL = lua_open();
	//luaopen_base(pL);
	//luaL_openlibs(pL);
	//luaL_dofile(pL, "Init.lua");
	//lua_getglobal(pL, "background");
	//if (!lua_istable(pL, -1))
	//{
	//	return 0;
	//}
	//lua_pushnumber(pL, 10);

	//if (lua_isnumber(pL, -1))
	//{
	//	cout << "lua_isnumber"<< endl;
	//}

	//if (lua_istable(pL, -2))
	//{
	//	cout << "lua_istable"<< endl;
	//}

	//lua_State* pL = lua_open();
	//luaopen_base(pL);
	//luabind::open(pL);


	//static char key = 'k';
	//lua_pushlightuserdata(L, (void *)&key);
	//lua_setglobal(L, "ddee");
	//luaL_dofile(L, "tabletest.lua");
	
	//dugaodaInfo *pp;
	//luabind:object l_oboo(L, pp);
	//l_oboo.push(pp);


	//功能: 执行挂起一段时间
	//Sleep(DWORD dwMilliseconds);
	//#include <windows.h>
	//(Sleep函数存放头文件:WinBase.h)
	//Sleep()单位为毫秒,sleep()单位为秒(如果需要更精确可以用usleep单位为微秒)

	//HANDLE CreateThread(LPSECURITY_ATTRIBUTES lpThreadAttributes,//线程安全
	//	DWORD dwStackSize,						//线程堆栈的初始化大小,等于0时,为系统默认的堆栈大小
	//	LPTHREAD_START_ROUTINE lpStartAddress,	//线程函数
	//	LPVOID lpParameter,						//线程参数
	//	DWORD dwCreationFlags,					//创建方式
	//	LPDWORD lpThreadId						//线程标识符
	//	);
	//system("pause");
	功能说明:等待所有的线程被激发  WaitForMultipleObjects() 
	功能说明:阻塞等待请求资源,这个函数在多线程中可以起到阻塞线程的作用	WaitForSingleObject() 
	1.使用CreateThread来创建线程
	//printf("创建多线程");
	//HANDLE handle = CreateThread(NULL, 0, ThreadFun, NULL, 0, NULL);
	//WaitForSingleObject(handle, INFINITE);
	


	2.使用_beginthreadex来创建线程
	创建线程的函数_beginthreadex()
	_beginthreadex();
	//const int THREAD_NUM = 5;
	//HANDLE handle[THREAD_NUM];
	//for (int i = 0; i < THREAD_NUM; i++)
	//{
	//	handle[i] = (HANDLE)_beginthreadex(NULL, 0, ThreadFun2, NULL, 0, NULL);
	//}
	//WaitForMultipleObjects(THREAD_NUM, handle, TRUE, INFINITE);


	3.模拟多个用户登录
	//g_nLoginCount = 0;
	//HANDLE handle[THREAD_NUM];
	//for (int i = 0; i < THREAD_NUM; i++)
	//{
	//	handle[i] = (HANDLE)_beginthreadex(NULL, 0, ThreadFun3, NULL, 0, NULL);
	//}
	//WaitForMultipleObjects(THREAD_NUM, handle, TRUE, INFINITE);
	//printf("有%d个用户登录后记录结果是%dn", THREAD_NUM, g_nLoginCount);

	4.增加点用户来试试,现在模拟50个用户登录,为了便于观察结果,在程序中将50个用户登录过程重复20次
	//int nNum = 20;
	//while (nNum--)
	//{
	//	g_nLoginCount = 0;
	//	int i = 0;
	//	HANDLE handle[THREAD_NUM];
	//	for (i = 0; i < THREAD_NUM; i++)
	//	{
	//		handle[i] = (HANDLE)_beginthreadex(NULL, 0, ThreadFun4, NULL, 0, NULL);
	//	}
	//	WaitForMultipleObjects(THREAD_NUM, handle, TRUE, INFINITE);
	//	printf("有%d个用户登录后记录结果是%dn", THREAD_NUM, g_nLoginCount);  
	//}

	5.一个经典的多线程同步问题,原子操作 Interlocked系列函数
	//g_nNum = 0;
	//HANDLE handle[THREAD_NUM5];
	//int i = 0;
	//while (i < THREAD_NUM5)
	//{
	//	handle[i] = (HANDLE)_beginthreadex(NULL, 0, ThreadFun5, &i, 0, NULL);
	//	i++;
	//}

	//WaitForMultipleObjects(THREAD_NUM5, handle, TRUE, INFINITE);

	//6.经典线程同步 关键段CS  临界区
	//函数说明:定义关键段变量后必须先初始化。
	//void InitializeCriticalSection(LPCRITICAL_SECTION lpCriticalSection);

	//函数说明:用完之后记得销毁。
	//void DeleteCriticalSection(LPCRITICAL_SECTION lpCriticalSection);

	//函数说明:系统保证各线程互斥的进入关键区域。
	//void EnterCriticalSection(LPCRITICAL_SECTION lpCriticalSection);

	//函数功能:离开关关键区域
	//void LeaveCriticalSection(LPCRITICAL_SECTIONlpCriticalSection);


	//函数功能:初始化关键段并设置旋转次数
	//BOOL InitializeCriticalSectionAndSpinCount(LPCRITICAL_SECTION lpCriticalSection, DWORD dwSpinCount);
	
	//函数功能:修改关键段的旋转次数
	//DWORD SetCriticalSectionSpinCount(LPCRITICAL_SECTION lpCriticalSection, DWORD dwSpinCount)

	关键段初始化
	//InitializeCriticalSection(&g_csThreadParameter);
	//InitializeCriticalSection(&g_csThreadCode);

	//HANDLE handle[THREAD_NUM6];
	//g_nResAmount = 0;
	//int i = 0;
	//while (i < THREAD_NUM6)
	//{
	//	EnterCriticalSection(&g_csThreadParameter);
	//	handle[i] = (HANDLE)_beginthreadex(NULL, 0, ThreadFun6, &i, 0, NULL);
	//	++i;
	//}
	//WaitForMultipleObjects(THREAD_NUM6, handle, TRUE, INFINITE);

	//DeleteCriticalSection(&g_csThreadParameter);
	//DeleteCriticalSection(&g_csThreadCode);

	//上面会出现一个问题,会对同一个线程多次打印。临界区只能用于
	//线程间的互相限制,不能对主线程限制


	//7. 经典线程同步 事件Event

	//函数功能:根据名称获得一个事件句柄。
	//函数原型:
	//
	//	HANDLE OpenEvent(
	//
	//	DWORDdwDesiredAccess,
	//
	//	BOOLbInheritHandle,
	//
	//	LPCTSTRlpName     //名称
	//
	//	);

	//函数功能:触发事件
	//BOOL SetEvent(HANDLE hEvent);

	//函数功能:将事件设为末触发
	//BOOL ResetEvent(HANDLE hEvent);

	//函数功能:将事件触发后立即将事件设置为未触发,相当于触发一个事件脉冲。
	//BOOL PulseEvent(HANDLE hEvent);

	//g_hThreadEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
	//InitializeCriticalSection(&g_csThreadCode7);

	//HANDLE handle[THREAD_NUM7];
	//g_nResNum7 = 0;
	//int i = 0;
	//while (i < THREAD_NUM7)
	//{
	//	handle[i] = (HANDLE)_beginthreadex(NULL, 0, ThreadFun7, &i, 0, NULL);
	//	WaitForSingleObject(g_hThreadEvent, INFINITE);
	//	i++;
	//}
	//WaitForMultipleObjects(THREAD_NUM, handle, TRUE, INFINITE);

	//CloseHandle(g_hThreadEvent);
	//DeleteCriticalSection(&g_csThreadCode7);


	8.快线程 慢线程
	//BOOL bManualReset = TRUE;
	创建事件 第二个参数手动置位TRUE,自动置位FALSE
	//g_hThreadEvent8 = CreateEvent(NULL, bManualReset, FALSE, NULL);

	//if (bManualReset == TRUE)  
	//	printf("当前使用手动置位事件n");  
	//else  
	//	printf("当前使用自动置位事件n"); 

	//char szFastThreadName[5][30] = {"快线程1000", "快线程1001", "快线程1002", "快线程1003", "快线程1004"};
	//char szSlowThreadName[2][22] = {"慢线程196", "慢线程197"};
	//for (int i = 0; i < 5; i++)
	//{
	//	_beginthreadex(NULL, 0, FastThreadFun, szFastThreadName[i], 0, NULL);
	//}

	//for (int i = 0; i < 2; i++)  
	//	_beginthreadex(NULL, 0, SlowThreadFun, szSlowThreadName[i], 0, NULL);  

	//Sleep(50);//保证快线程全部启动
	//printf("现在主线程触发一个事件脉冲 - PulseEvent()n"); 
	//PulseEvent(g_hThreadEvent8);

	//Sleep(3000);
	//printf("时间到,主线程结束运行n");  
	//CloseHandle(g_hThreadEvent8); 

	//9.经典线程同步 互斥量Mutex
	//函数功能:创建互斥量(注意与事件Event的创建函数对比)

	//函数原型:
	//HANDLE CreateMutex(
	//LPSECURITY_ATTRIBUTES lpMutexAttributes,
	//BOOL bInitialOwner,   
	//LPCTSTR lpName
	//);

	//打开互斥量
	//函数原型:
	//HANDLE OpenMutex(
	//DWORD dwDesiredAccess,
	//BOOL bInheritHandle,
	//LPCTSTR lpName     //名称
	//);

	//函数说明:
	//触发互斥量
	//访问互斥资源前应该要调用等待函数,结束访问时就要调用ReleaseMutex()来表示自己已经结束访问,其它线程可以开始访问了。
	//函数原型:BOOL ReleaseMutex (HANDLE hMutex)
	
	//初始化互斥量与关键段 第二个参数为TRUE表示互斥量为创建线程所有  
	//g_hThreadParameter9 = CreateMutex(NULL, FALSE, NULL);
	//InitializeCriticalSection(&g_csThreadCode9);

	//HANDLE handle[THREAD_NUM9];
	//g_nResAmount9 = 0;
	//int i = 0;
	//while (i < THREAD_NUM9)
	//{
	//	handle[i] = (HANDLE)_beginthreadex(NULL, 0, ThreadFun9, &i, 0, NULL);
	//	WaitForSingleObject(g_hThreadParameter9, INFINITE); //等待互斥量被触发
	//	i++;
	//}
	//WaitForMultipleObjects(THREAD_NUM9, handle, TRUE, INFINITE);

	销毁互斥量和关键段
	//CloseHandle(g_hThreadParameter9);
	//DeleteCriticalSection(&g_csThreadCode9);
	//for (int i = 0;i < THREAD_NUM9; ++i)
	//{
	//	CloseHandle(handle[i]);
	//}

	与关键段类似,互斥量也是不能解决线程间的同步问题

	//HANDLE hMutex = CreateMutex(NULL, TRUE, MUTEX_NAME);
	//printf("互斥量已经创建,现在按任意键出发互斥量");
	//getch();
	exit(0);
	//ReleaseMutex(hMutex);
	//printf("互斥量已经触发");
	//CloseHandle(hMutex);

	/*1.互斥量是内核对象,它与关键段都有“线程所有权”所以不能用于线程的同步。
	2.互斥量能够用于多个进程之间线程互斥问题,并且能完美的解决某进程意外终止所造成的“遗弃”问题。*/

	//10.经典线程同步 信号量Semaphore

	//g_hThreadParameter10 = CreateSemaphore(NULL, 0, 1, NULL);//当前0个资源,最大允许1个同时访问
	//InitializeCriticalSection(&g_csThreadCode10);

	//HANDLE handle[THREAD_NUM10];
	//g_nResNum10 = 0;
	//int i = 0;
	//while (i < THREAD_NUM10)
	//{
	//	handle[i] = (HANDLE)_beginthreadex(NULL, 0, ThreadFun10, &i, 0, NULL);
	//	WaitForSingleObject(g_hThreadParameter10, INFINITE);
	//	++i;
	//}
	//WaitForMultipleObjects(THREAD_NUM, handle, TRUE, INFINITE);

	//DeleteCriticalSection(&g_csThreadCode10);
	//CloseHandle(g_hThreadParameter10);
	//for (i = 0; i < THREAD_NUM10; i++)
	//{
	//	CloseHandle(handle[i]);
	//}

	//11.生产者消费者问题
	//11.1
	//1生产者 1消费者 1缓冲区  
	//使用二个事件,一个表示缓冲区空,一个表示缓冲区满。  
	//再使用一个关键段来控制缓冲区的访问 

	//InitializeCriticalSection(&g_cs);
	创建二个自动复位事件,一个表示缓冲区是否为空,另一个表示缓冲区是否已经处理
	//g_hEventBufferEmpty = CreateEvent(NULL, FALSE, TRUE, NULL);
	//g_hEventBufferFull = CreateEvent(NULL, FALSE, TRUE, NULL);

	//const int THREADNUM = 2;
	//HANDLE hThread[THREADNUM];

	//hThread[0] = (HANDLE)_beginthreadex(NULL, 0, ProducerThreadFun, NULL, 0, NULL);
	//hThread[1] = (HANDLE)_beginthreadex(NULL, 0, ConsumerThreadFun, NULL, 0, NULL);
	//WaitForMultipleObjects(THREADNUM, hThread, TRUE, INFINITE);

	//for (int i = 0; i < THREADNUM; ++i)
	//{
	//	CloseHandle(hThread[i]);
	//}

	//CloseHandle(ProducerThreadFun);
	//CloseHandle(ConsumerThreadFun);
	//DeleteCriticalSection(&g_cs);

	1生产者 2消费者 4缓冲区  
	使用二个事件,一个表示缓冲区空,一个表示缓冲区满。  
	再使用一个关键段来控制缓冲区的访问 

	//InitializeCriticalSection(&g_cs2);

	初始化信号量,一个记录有产品的缓冲区个数,另一个记录空缓冲区个数.
	//g_hSemaphoreBufferEmpty2 = CreateSemaphore(NULL, 4, 4, NULL);
	//g_hSemaphoreBufferFull2  = CreateSemaphore(NULL, 0, 4, NULL);
	//g_i = 0;
	//g_j = 0;
	//memset(g_nBuffer2, 0, sizeof(g_nBuffer2));

	//const int THREADNUM = 3;
	//HANDLE hThread[THREADNUM];
	//hThread[0] = (HANDLE)_beginthreadex(NULL, 0, ProducerThreadFun2, NULL, 0, NULL);
	//hThread[1] = (HANDLE)_beginthreadex(NULL, 0, ConsumerThreadFun2, NULL, 0, NULL);
	//hThread[2] = (HANDLE)_beginthreadex(NULL, 0, ConsumerThreadFun2, NULL, 0, NULL);
	//WaitForMultipleObjects(THREADNUM, hThread, TRUE, INFINITE);

	//for (int i = 0; i < THREADNUM; i++)  
	//	CloseHandle(hThread[i]);  

	销毁信号量和关键段  
	//CloseHandle(g_hSemaphoreBufferEmpty2);  
	//CloseHandle(g_hSemaphoreBufferFull2);  
	//DeleteCriticalSection(&g_cs2);  


	12.读者与写者问题 

	//
	//InitializeCriticalSection(&g_cs12);
	//InitializeCriticalSection(&g_cs_writer_count);

	//g_hEventWriter = CreateEvent(NULL, TRUE, TRUE, NULL);
	//g_hEventNoReader = CreateEvent(NULL, TRUE, TRUE, NULL);

	//g_nReaderCount = 0;

	//int i;
	//HANDLE hThread[READER_NUM + 1];

	先启动二个读者线程
	//for (i = 1; i <= 2; i++)
	//{
	//	hThread[i] = (HANDLE)_beginthreadex(NULL, 0, ReaderThreadFun, NULL, 0, NULL);
	//}

	启动写者线程
	//hThread[0] = (HANDLE)_beginthreadex(NULL, 0, WriterThreadFun, NULL, 0, NULL);

	//Sleep(50);
	启动其他读者线程
	//for (; i <= READER_NUM; i++)
	//{
	//	hThread[i] = (HANDLE)_beginthreadex(NULL, 0, ReaderThreadFun, NULL, 0, NULL);
	//}

	//WaitForMultipleObjects(READER_NUM, hThread, TRUE, INFINITE);

	//for (i = 0; i <= READER_NUM; i++)
	//{
	//	CloseHandle(hThread[i]);
	//}

	销毁事件和信号量
	//CloseHandle(g_hEventWriter);
	//CloseHandle(g_hEventNoReader);
	//
	//DeleteCriticalSection(&g_cs12);
	//DeleteCriticalSection(&g_cs_writer_count);

	//13 关于CreateEvent中的参数如何使用
	//手动置为非激发(无信号)状态:ResetEvent 
	//设置为激发(有信号)状态:SetEvent; 
	//当一个等待线程被释放时,自动重置状态为无信号状态。
	//只有事件有信号的时候线程函数才会被触发

	//14.读写锁


	//InitializeCriticalSection(&g_cs14);
	初始化读写锁
	//InitializeSRWLock(&g_srwLock);

	//HANDLE hThread[READER_NUM + 1];  
	//int i;  
	先启动二个读者线程  
	//for (i = 1; i <= 2; i++)  
	//	hThread[i] = (HANDLE)_beginthreadex(NULL, 0, ReaderThreadFun, NULL, 0, NULL);  
	启动写者线程  
	//hThread[0] = (HANDLE)_beginthreadex(NULL, 0, WriterThreadFun, NULL, 0, NULL);  
	//Sleep(50);  
	最后启动其它读者结程  
	//for ( ; i <= READER_NUM; i++)  
	//	hThread[i] = (HANDLE)_beginthreadex(NULL, 0, ReaderThreadFun, NULL, 0, NULL);  
	//WaitForMultipleObjects(READER_NUM + 1, hThread, TRUE, INFINITE);  
	//for (i = 0; i < READER_NUM + 1; i++)  
	//	CloseHandle(hThread[i]);  

	销毁关键段  
	//DeleteCriticalSection(&g_cs14); 

//typedef unsigned int INT;
//INT ABC;
//ABC = 100000;
//
//typedef int dugaodaarray[100];
//
//dugaodaarray tmp;
//tmp[1] = 10;
//int tmp[100];

//typedef struct t_node
//{
//	int a;
//	int b;
//}Node;
//Node tmpabc;
//tmpabc.a= 10;
//tmpabc.
//typedef void (*DUGAODAFUNCTION)(int);
//void printabc(int x)
//{
//
//}
//DUGAODAFUNCTION pABC;
//pABC = printabc;
//
//
//
//(*pABC)(10);
//#pragma once
//#ifdef WINDOWS
//#endif
//
//#define ABC 100;
//#undef ABC;

//#ifndef _SOMEFILE_H_
//#define _SOMEFILE_H_
//.......... // 一些声明语句
//#endif

	return 0; 
}

最后

以上就是精明翅膀为你收集整理的多线程代码编写的全部内容,希望文章能够帮你解决多线程代码编写所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(82)

评论列表共有 0 条评论

立即
投稿
返回
顶部