一、多线程基础知识
1、C++11的多线程库
C++11标准引入了对多线程的支持,它定义了<thread>
头文件以及std::thread
类,可以方便地进行线程创建、结束、等待等操作。下面是一个简单的示例:
#include <iostream> #include <thread> void hello() { std::cout << "Hello World!<br>" << std::endl; } int main() { std::thread t(hello); t.join(); return 0; }
2、线程间的数据共享
多线程编程中,不同线程之间需要共享数据,但共享数据容易引起线程安全问题,需要使用互斥量std::mutex
来进行保护。
#include <iostream> #include <thread> #include <mutex> std::mutex mu; int g_count = 0; void increment() { mu.lock(); ++g_count; mu.unlock(); } int main() { std::thread t1(increment); std::thread t2(increment); t1.join(); t2.join(); std::cout << "g_count = " << g_count << std::endl; return 0; }
二、多线程优化策略
1、任务分解
将大任务分成多个小任务,每个小任务由一个线程执行,通过这种方式可以提高程序的整体处理速度。
#include <iostream> #include <thread> #include <vector> #include <cmath> const int N = 1000000; void calculate(int start, int end, double* result) { for(int i = start; i < end; ++i) { result[i] = sqrt(i); } } int main() { double* result = new double[N]; std::vector<std::thread> threads; const int thread_count = std::thread::hardware_concurrency(); const int block_size = N / thread_count; for(int i = 0; i < thread_count; ++i) { int start = i * block_size; int end = (i == thread_count-1) ? N : (i+1) * block_size; threads.push_back(std::thread(calculate, start, end, result)); } for(auto& t : threads) { t.join(); } delete[] result; return 0; }
2、避免不必要的复制
多线程程序中,有时需要传递大量数据到线程执行的函数中,如果直接传递这些数据,会造成大量的复制开销,可以通过使用指针或引用的方式,减小函数参数的复制。
#include <iostream> #include <thread> #include <cstring> #include <cstdlib> void worker(const char* str) { char* s = (char*)malloc(sizeof(str)+1); std::strcpy(s, str); std::cout << "Thread " << std::this_thread::get_id() << " : " << s << std::endl; free(s); } int main() { const char* str = "Hello World!"; std::thread t(worker, str); t.join(); return 0; }
三、多线程应用场景
1、网络编程
网络编程中,需要同时处理多个客户端的请求,通过多线程可以提高服务器的并发处理性能。
//Server代码 #include <iostream> #include <thread> #include <chrono> #include <string> #include <cstring> #include <vector> #include <unistd.h> #include <sys/socket.h> #include <netinet/in.h> const int PORT = 8888; int server_fd = 0, client_fd = 0; bool is_running = true; std::vector<std::thread> threads; void client_thread(int fd) { char buffer[1024]; struct sockaddr_in client_addr; socklen_t client_addr_len = sizeof(client_addr); while(is_running) { memset(buffer, 0, sizeof(buffer)); int n = recvfrom(fd, buffer, sizeof(buffer), 0, (struct sockaddr *)&client_addr, &client_addr_len); if(n == -1) continue; //处理客户端请求 std::cout << "Thread " << std::this_thread::get_id() << " : receive message from " << inet_ntoa(client_addr.sin_addr) << " : " << ntohs(client_addr.sin_port) << ", message:" << buffer << std::endl; } } void init_server() { server_fd = socket(AF_INET, SOCK_STREAM, 0); struct sockaddr_in server_addr; memset(&server_addr, 0, sizeof(server_addr)); server_addr.sin_family = AF_INET; server_addr.sin_port = htons(PORT); server_addr.sin_addr.s_addr = htonl(INADDR_ANY); bind(server_fd, (struct sockaddr *)&server_addr, sizeof(server_addr)); listen(server_fd, 10); std::cout << "Server start ..." << std::endl; while(is_running) { client_fd = accept(server_fd, NULL, NULL); std::thread t(client_thread, client_fd); threads.push_back(std::move(t)); } for(auto& t : threads) { if(t.joinable()) t.join(); } } void stop_server() { is_running = false; close(client_fd); close(server_fd); } int main() { std::thread t(init_server); getchar(); stop_server(); t.join(); return 0; }
2、数据处理
数据处理中,经常需要进行大量的计算、排序、查找等操作,通过多线程可以加快计算速度。
#include <iostream> #include <thread> #include <vector> #include <algorithm> #include <random> const long long N = 100000000000; const int block_size = 1000000; std::vector<std::thread> threads; double* a; void calculate(int start, int end, double* result) { for(long long i = start; i < end; ++i) { result[i] = sqrt(i); } } int main() { a = new double[N]; for(int i = 0; i < N; i += block_size) { int start = i; int end = (i + block_size < N) ? i + block_size : N; threads.push_back(std::thread(calculate, start, end, a)); } for(auto& t : threads) { t.join(); } std::sort(a, a+N); delete[] a; return 0; }
四、结语
本文介绍了C++多线程编程的基础知识、优化策略和应用场景,但是多线程编程也有其困难和缺陷,需要开发者在使用时进行综合考虑。