C++线程的用法《C++多线程编程实战》

本文介绍了一个CMySQL类的实现,用于连接MySQL数据库,执行读写操作,并通过多线程进行数据库测试。该类使用单例模式管理实例,并提供了连接、断开连接、读取数据和写入数据的方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

需要安装MySQL C Connector

  • CMYSQL.h
#include "pch.h"
#include <stdio.h>
#include <stdlib.h>
#include <mysql.h>

class CMySQL
{
public:
	static CMySQL* CreateInstance(char* szHostName, char* szDatabase,
		char* szUserId, char* szPassword);
	static void ReleaseInstance();
	bool ConnectInstance();
	bool DisconnectInstance();
	bool ReadData(char* szQuery, char* szResult, size_t uBufferLenght);
	bool WriteData(char* szQuery, char* szResult, size_t uBufferLenght);
private:
	CMySQL(char* szHostName, char* szDatabase, char* szUserId, char*
		szPassword);
	~CMySQL();
	char* szHostName;
	char* szDatabase;
	char* szUserId;
	char* szPassword;
	MYSQL* mysqlConnection;
	static CMySQL* mySqlInstance;
};



  • CMYSQL.cpp
#include "pch.h"
#include "CMYSQL.h"
#include <string>

CMySQL* CMySQL::mySqlInstance = NULL;
CMySQL* CMySQL::CreateInstance(char* szHostName, char* szDatabase,
	char* szUserId, char* szPassword)
{
	if (mySqlInstance)
	{
		return mySqlInstance;
	}
	return new CMySQL(szHostName, szDatabase, szUserId, szPassword);
}
void CMySQL::ReleaseInstance()
{
	if (mySqlInstance)
	{
		delete mySqlInstance;
	}
}

CMySQL::CMySQL(char* szHostName, char* szDatabase, char*szUserId,
	char* szPassword)
{
	size_t length = 0;
	this->szHostName = new char[length = strlen(szHostName) + 1];
	strcpy_s(this->szHostName, length, szHostName);
	this->szDatabase = new char[length = strlen(szDatabase) + 1];
	strcpy_s(this->szDatabase, length, szDatabase);
	this->szUserId = new char[length = strlen(szUserId) + 1];
	strcpy_s(this->szUserId, length, szUserId);

	this->szPassword = new char[length = strlen(szPassword) + 1];
	strcpy_s(this->szPassword, length, szPassword);
}

CMySQL::~CMySQL()
{
	delete szHostName;
	delete szDatabase;
	delete szUserId;
	delete szPassword;
}

bool CMySQL::ConnectInstance()
{
	MYSQL* mysqlLink = NULL;

	try
	{
		mysqlConnection = mysql_init(NULL);
		mysqlLink = mysql_real_connect(mysqlConnection, szHostName,
			szUserId, szPassword, szDatabase, 3306, NULL, 0);
	}
	catch (...)
	{
		mysqlConnection = 0;
		return false;
	}
	return mysqlLink ? true : false;
}

bool CMySQL::DisconnectInstance()
{
	try
	{
		mysql_close(mysqlConnection);
		return true;
	}
	catch (...)
	{
		return false;
	}
}

bool CMySQL::ReadData(char* szQuery, char* szResult, size_t uBufferLenght)
{
	int mysqlStatus = 0;
	MYSQL_RES* mysqlResult = NULL;
	MYSQL_ROW mysqlRow = NULL;
	my_ulonglong numRows = 0;
	unsigned numFields = 0;
	try
	{
		mysqlStatus = mysql_query(mysqlConnection, szQuery);
		if (mysqlStatus)
		{
			return false;
		}
		else
		{
			mysqlResult = mysql_store_result(mysqlConnection);
		}
		if (mysqlResult)
		{
			numRow = mysql_num_rows(mysqlResult);
			numFields = mysql_num_fields(mysqlResult);
		}
		mysqlRow = mysql_fetch_row(mysqlResult);
		if (mysqlRow)
		{
			if (!mysqlRow[0])
			{
				mysql_free_result(mysqlResult);
				return false;
			}
		}
		else
		{
			mysql_free_result(mysqlResult);
			return false;
		}

		size_t szResultLength = strlen(mysqlRow[0]) + 1;
		strcpy_s(szResult, szResultLength > uBufferLenght ?
			uBufferLenght : szResultLength, mysqlRow[0]);

		if (mysqlResult)
		{
			mysql_free_result(mysqlResult);
			mysqlResult = NULL;
		}
	}
	catch (...)
	{
		return false;
	}
	return true;
}

bool CMySQL::WriteData(char* szQuery, char* szResult, size_t
	uBufferLenght)
{
	try
	{
		int mysqlStatus = mysql_query(mysqlConnection, szQuery);
		if (mysqlStatus)
		{
			size_t szResultLength = strlen("Failed!") + 1;
			strcpy_s(szResult, szResultLength > uBufferLenght ?
				uBufferLenght : szResultLength, "Failed!");
			return false;
		}
	}
	catch (...)
	{
		size_t szResultLength = strlen("Exception!") + 1;
		strcpy_s(szResult, szResultLength > uBufferLenght ?
			uBufferLenght : szResultLength, "Exception!");
		return false;
	}

	size_t szResultLength = strlen("Success") + 1;
	strcpy_s(szResult, szResultLength > uBufferLenght ?
		uBufferLenght : szResultLength, "Success");
	return true;
}


  • MultithreadedDBTest.cpp
// MultithreadedDBTest.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//

#include "pch.h"
#include "CMYSQL.h"
#include <windows.h>

#define BLOCK_SIZE 4096
#define THREADS_NUMBER 3

typedef struct
{
	char szQuery[BLOCK_SIZE];
	char szResult[BLOCK_SIZE];
	bool bIsRead;
} QUERYDATA, *PQUERYDATA;

CRITICAL_SECTION cs;
CMySQL* mySqlInstance = NULL;

DWORD WINAPI StartAddress(LPVOID lpParameter)
{
	PQUERYDATA pQueryData = (PQUERYDATA)lpParameter;
	EnterCriticalSection(&cs);
	if (mySqlInstance->ConnectInstance())
	{
		if (pQueryData->bIsRead)
		{
			memset(pQueryData->szResult, 0, BLOCK_SIZE - 1);
			mySqlInstance->ReadData(pQueryData->szQuery,
				pQueryData->szResult, BLOCK_SIZE - 1);
		}
		else
		{
			mySqlInstance->WriteData(pQueryData->szQuery,
				pQueryData->szResult, BLOCK_SIZE - 1);
		}
		mySqlInstance->DisconnectInstance();
	}
	LeaveCriticalSection(&cs);
	return 0L;
}

int main()
{
	InitializeCriticalSection(&cs);
	mySqlInstance = CMySQL::CreateInstance(
		"mysql.services.expert.its.me", "expertit_9790OS",
		"expertit_9790", "$dbpass_1342#");
	if (mySqlInstance)
	{
		HANDLE hThreads[THREADS_NUMBER];
		QUERYDATA queryData[THREADS_NUMBER] =
		{
			{ "select address from clients where id = 3;",
			"", true },
			{ "update clients set name='Merrill & Lynch' where id=2;",
			"", false },
			{ "select name from clients where id = 2;",
			"", true }
		};
		for (int iIndex = 0; iIndex < THREADS_NUMBER; iIndex++)
		{
			hThreads[iIndex] = CreateThread(NULL, 0,
				(LPTHREAD_START_ROUTINE)StartAddress,
				&queryData[iIndex], 0, 0);
		}
		WaitForMultipleObjects(THREADS_NUMBER, hThreads, TRUE, INFINITE);
		for (int iIndex = 0; iIndex < THREADS_NUMBER; iIndex++)
		{
			printf_s("%s\n", queryData[iIndex].szResult);
		}
		CMySQL::ReleaseInstance();
	}
	DeleteCriticalSection(&cs);
    return system("pause"); 
}

### 回答1: 多线程实战PDF是一本介绍多线程编程实践的PDF电子书。多线程是指在一个程序中同时运行多个线程,每个线程都可以执行不同的任务。多线程可以提高程序的执行效率、响应速度和资源利用率,是现代计算机应用中常用的技术。 该电子书主要介绍了多线程编程的原理、方法和实践经验。首先,它从多线程的基本概念和原理入手,介绍了线程的创建、启动、终止和同步等基本操作。然后,它详细介绍了多线程编程中常见的问题和解决方案,如线程间的通信、资源竞争、死锁和并发性问题等。同时,它还介绍了多线程编程的一些高级技术,如线程池、信号量、互斥锁和条件变量等。 该电子书还通过实例代码和案例分析,给读者提供了一些实战经验。例如,它介绍了如何利用多线程实现文件下载、图像处理、网络爬虫和并行计算等常见应用场景。同时,它还介绍了如何利用多线程优化程序性能,如通过并行计算加速算法的运行、利用线程池提高任务处理能力等。 总之,多线程实战PDF是一本介绍多线程编程实践的电子书,它详细介绍了多线程编程的原理、方法和实践经验,并通过实例代码和案例分析给读者提供了一些实战经验。对于想要学习和应用多线程编程的人来说,这本电子书是一个很好的参考资料。 ### 回答2: 多线程是一种可以同时执行多个任务的编程技术,它可以提高程序的运行效率和响应速度。在实际应用中,我们可以利用多线程来处理一些需要同时执行的任务,例如同时下载多个文件、同时进行图像处理等。 在实现多线程的应用中,我们通常会遇到一些问题,如线程之间的数据共享、线程的同步与互斥等。为了更好地理解多线程的使用和解决这些问题,可以通过实践来加深理解。 以一个多线程实战PDF为例,假设我们需要编写一个程序,能够同时下载多个PDF文件并保存到本地。我们可以首先定义一个下载函数,在该函数中使用多线程来实现同时下载多个PDF文件的功能。 在下载函数中,我们可以通过创建多个线程,并将每个线程分配到不同的下载任务上。通过在每个线程中实现下载逻辑,我们可以同时进行多个文件的下载,提高下载效率。 同时,为了确保线程之间的数据共享和操作的正确性,我们可以使用一些同步机制,如互斥锁(mutex)和条件变量(condition),来保证线程之间的协作和安全性。通过这些同步机制,我们可以避免多个线程同时访问和修改共享资源的问题,保证下载的正确进行。 在实际编写的过程中,我们还可以优化多线程的性能,例如合理设置线程的数量、调整下载任务的分配策略等。同时,我们也需要考虑一些问题,如线程的优雅退出、线程的异常处理等,以确保程序的健壮性。 总之,多线程实战PDF是一个相当实用和有意义的应用场景,通过实践和理论相结合的方式,我们可以更好地理解和掌握多线程的使用,提高程序的效率和可靠性。 ### 回答3: C多线程实战PDF是一本介绍多线程编程并提供实际案例的电子书籍。多线程是指在一个程序中同时执行多个线程,可以充分利用计算机资源,提高程序的运行效率。本书通过具体的项目实例,重点讲解了如何在C语言中实现多线程编程。 本书首先介绍了多线程的概念和原理,包括线程的创建、同步与互斥、线程的调度等基本知识。然后通过实战项目,让读者学会如何使用多线程解决实际问题。这些实战案例涵盖了多个领域,如网络编程、图像处理、并行计算等,旨在帮助读者理解多线程的应用场景和技巧。 在实战案例中,读者将学习如何使用多线程编写一个简单的Web服务器,实现同时处理多个HTTP请求。同时,还可以学习如何使用多线程进行图像处理,例如并行地对图像进行压缩或特效处理。此外,本书还介绍了如何使用多线程进行并行计算,以提高程序的性能。 C多线程实战PDF适合有一定C语言编程基础的读者学习。通过阅读本书,读者可以深入了解多线程编程的原理和技术,掌握多线程编程的核心概念和方法,并能灵活应用于实际项目中。无论是对于想要提升编程技能的程序员,还是对于对多线程编程感兴趣的技术爱好者,本书都是一本很好的学习资料。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值