面试题答案
一键面试Kotlin与C++多线程协调避免数据竞争和死锁
- 共享数据保护
- 锁机制:在Kotlin层,使用
synchronized
关键字对共享数据进行同步访问。例如:
- 锁机制:在Kotlin层,使用
val sharedData = mutableListOf<Int>()
synchronized(sharedData) {
sharedData.add(1)
}
- 在C++层,使用互斥锁(`std::mutex`)。例如:
std::mutex mtx;
std::vector<int> sharedData;
{
std::lock_guard<std::mutex> lock(mtx);
sharedData.push_back(1);
}
- 线程同步
- 条件变量:在Kotlin中,可以使用
Condition
配合Object
的监视器实现条件等待和通知。例如:
- 条件变量:在Kotlin中,可以使用
val condition = Condition()
val monitor = Object()
Thread {
synchronized(monitor) {
while (!someCondition) {
condition.await(monitor)
}
// 执行任务
}
}.start()
synchronized(monitor) {
someCondition = true
condition.signal(monitor)
}
- 在C++中,使用`std::condition_variable`和`std::unique_lock`。例如:
std::condition_variable cv;
std::mutex mtx;
bool someCondition = false;
std::thread([&] {
std::unique_lock<std::mutex> lock(mtx);
while (!someCondition) {
cv.wait(lock);
}
// 执行任务
}).detach();
{
std::lock_guard<std::mutex> lock(mtx);
someCondition = true;
cv.notify_one();
}
- 避免死锁
- 按顺序加锁:确保在Kotlin和C++中,对多个锁的获取顺序一致。例如,如果在一个线程中先获取锁A再获取锁B,在其他线程中也遵循同样的顺序。
- 使用锁层次结构:为锁定义层次,高优先级的锁先获取,低优先级的后获取,避免循环依赖。
Kotlin协程与C++线程库(如pthread)协作
- Kotlin协程调用C++函数
- 通过JNI:在Kotlin中通过JNI调用C++的pthread函数。首先在Kotlin中声明本地方法:
external fun nativeThreadFunction()
- 在C++中实现该本地方法,并使用pthread创建线程:
extern "C" JNIEXPORT void JNICALL
Java_com_example_yourpackage_YourClass_nativeThreadFunction(JNIEnv *env, jobject thiz) {
pthread_t thread;
pthread_create(&thread, nullptr, [] (void* args) -> void* {
// 线程执行的任务
return nullptr;
}, nullptr);
pthread_join(thread, nullptr);
}
- C++线程调用Kotlin协程
- 使用Kotlin/Native:可以通过Kotlin/Native将Kotlin代码编译为C++兼容的库,然后在C++线程中调用Kotlin协程。例如,定义一个Kotlin函数:
fun coroutineFunction() = runBlocking {
// 协程任务
}
- 使用Kotlin/Native编译后,在C++中通过生成的接口调用该函数。
3. 数据传递与同步
- 通过JNI传递数据:在Kotlin和C++之间传递数据时,要注意数据的一致性和同步。例如,将Kotlin的List
转换为C++的std::vector
,并在传递前确保数据的状态正确。
- 使用共享内存或消息队列:对于大量数据或需要高效传递的数据,可以考虑使用共享内存或消息队列在Kotlin协程和C++线程之间进行通信,同时配合锁机制确保数据的一致性。