概述
// 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;
}
最后
以上就是精明翅膀为你收集整理的多线程代码编写的全部内容,希望文章能够帮你解决多线程代码编写所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复