在 C++ 中,std::thread
构造函数可以用于将参数传递给线程。这里是一个基本的示例,展示了如何使用 std::thread
来传递参数:
cpp
#include <iostream>
#include <thread>
// 定义一个被线程调用的函数
void threadFunc(int arg1, double arg2, std::string arg3) {
std::cout << "arg1: " << arg1 << ", arg2: " << arg2 << ", arg3: " << arg3 << std::endl;
}
int main() {
// 创建一个线程,并传递参数
std::thread t(threadFunc, 1, 3.14, "Hello, World!");
// 等待线程结束
t.join();
return 0;
}
在这个例子中,定义了一个函数 threadFunc
,它接受三个参数。然后在 main
函数中创建了一个线程,并将这三个参数传递给了 threadFunc
。
如果函数参数是引用类型,可以使用 std::ref
或 std::cref
来传递引用:
cpp
#include <iostream>
#include <thread>
#include <functional> // std::ref 和 std::cref 需要这个头文件
// 定义一个被线程调用的函数
void threadFunc(int &arg1, double &arg2, std::string &arg3) {
std::cout << "arg1: " << arg1 << ", arg2: " << arg2 << ", arg3: " << arg3 << std::endl;
}
int main() {
int arg1 = 1;
double arg2 = 3.14;
std::string arg3 = "Hello, World!";
// 创建一个线程,并传递参数引用
std::thread t(threadFunc, std::ref(arg1), std::ref(arg2), std::ref(arg3));
// 等待线程结束
t.join();
return 0;
}
在这个例子中,使用 std::ref
来传递变量的引用,这样就可以在 threadFunc
中修改这些变量的值。
std::ref
和 std::cref
是 C++11 引入的,用于在函数绑定或异步函数调用中引用成员函数或者非成员函数。这些函数主要在多线程中使用,目的是在函数调用中保持对象的引用,而不是复制对象。
std::ref
和 std::cref
的使用
-
std::ref
:
std::ref
用于在函数绑定或异步函数调用中引用非 const 对象。例如:cppstd::thread t(func, std::ref(myObj));
-
std::cref
:
std::cref
类似于std::ref
,但它用于引用 const 对象。例如:cppstd::thread t(func, std::cref(myObj));
这两个函数都定义在 <functional>
头文件中,因此在使用它们之前,必须包含这个头文件。
多线程示例
以下是一个示例,展示了如何使用 std::thread
和 std::promise
进行线程同步:
cpp
#include <iostream>
#include <thread>
#include <future>
#include <string>
int main() {
std::promise<std::string> promise;
std::future<std::string> future = promise.get_future();
std::thread t([&promise] {
std::string s = "hello";
std::this_thread::sleep_for(std::chrono::seconds(1));
promise.set_value(s);
});
t.join();
std::string value = future.get();
std::cout << value << std::endl;
return 0;
}
使用信号量的多线程示例
下面是一个使用信号量和互斥锁进行线程同步的示例:
cpp
#include <iostream>
#include <thread>
#include <vector>
#include <mutex>
#include <semaphore.h>
std::mutex mtx;
sem_t sem;
int counter = 0;
void increment_counter(int id) {
sem_wait(&sem);
std::lock_guard<std::mutex> lock(mtx);
std::this_thread::sleep_for(std::chrono::milliseconds(100));
counter++;
std::cout << "Thread " << id << " incremented counter to " << counter << std::endl;
sem_post(&sem);
}
void read_counter(int id) {
sem_wait(&sem);
std::lock_guard<std::mutex> lock(mtx);
std::this_thread::sleep_for(std::chrono::milliseconds(100));
std::cout << "Thread " << id << " read counter value " << counter << std::endl;
sem_post(&sem);
}
int main() {
sem_init(&sem, 0, 5);
std::vector<std::thread> threads;
for (int i = 0; i < 10; ++i) {
if (i % 2 == 0) {
threads.push_back(std::thread(increment_counter, i));
} else {
threads.push_back(std::thread(read_counter, i));
}
}
for (auto &thread : threads) {
thread.join();
}
sem_destroy(&sem);
return 0;
}
在这个示例中,使用了信号量和互斥锁来控制对共享资源 counter
的访问。这样可以确保多个线程安全地访问和修改共享资源。