C++多线程竞争时经常用到互斥量用std::mutex,它可以单独使用,也可以和互斥锁在一起使用。
std::mutex单独使用的话就lock()加锁,用unlock()解锁。
为了方便的话可以用用互斥锁lock_guard,lock_guard会在创建时自动加锁,并且在作用域结束时自动析构释放锁。
lock_guard只能在创建时加锁,在作用域结束时释放锁,如果想中间释放锁呢,此时就需要加强版的unique_lock了,unique_lock可以随时加锁和解锁,并且可以和条件变量 std::condition_variable一起使用。
来个ndk demo
#include <jni.h>
#include <string>
#include <android/log.h>
#define LOG_TAG "MyCTestLog"
#define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, __VA_ARGS__)
#include <iostream>
#include <mutex>
#include <thread>
#include <stack>
using namespace std;
class MutexTest
{
public:
MutexTest() : m_mutex() { }
~MutexTest() { }
void Run(int n, char c)
{
LOGD("Push,n=%d,c=%c",n,c);
int b;
m_mutex.lock();
//std::unique_lock<std::mutex> lg(m_mutex);
for (int i = 0; i < n; i++)
{
LOGD("%c,i=%d",c,i);
}
m_mutex.unlock();
}
private:
std::mutex m_mutex;
};
extern "C" JNIEXPORT jstring JNICALL
Java_com_example_ndkapplication_MainActivity_stringFromJNI(
JNIEnv* env,
jobject /* this */) {
std::string hello = "Hello from C++";
MutexTest test;
std::thread mutexTestThread1(&MutexTest::Run, &test, 10, 'a');
std::thread mutexTestThread2(&MutexTest::Run, &test, 5, 'b');
mutexTestThread1.join(); //join主线程等待
mutexTestThread2.detach(); //detach主线程分离,无需等待
return env->NewStringUTF(hello.c_str());
}
log打印如下:
2020-07-09 07:30:52.731 13150-13232/com.example.ndkapplication D/MyCTestLog: Push,n=10,c=a
2020-07-09 07:30:52.731 13150-13233/com.example.ndkapplication D/MyCTestLog: Push,n=5,c=b
2020-07-09 07:30:52.731 13150-13232/com.example.ndkapplication D/MyCTestLog: a,i=0
2020-07-09 07:30:52.731 13150-13232/com.example.ndkapplication D/MyCTestLog: a,i=1
2020-07-09 07:30:52.731 13150-13232/com.example.ndkapplication D/MyCTestLog: a,i=2
2020-07-09 07:30:52.731 13150-13232/com.example.ndkapplication D/MyCTestLog: a,i=3
2020-07-09 07:30:52.731 13150-13232/com.example.ndkapplication D/MyCTestLog: a,i=4
2020-07-09 07:30:52.731 13150-13232/com.example.ndkapplication D/MyCTestLog: a,i=5
2020-07-09 07:30:52.731 13150-13232/com.example.ndkapplication D/MyCTestLog: a,i=6
2020-07-09 07:30:52.731 13150-13232/com.example.ndkapplication D/MyCTestLog: a,i=7
2020-07-09 07:30:52.731 13150-13232/com.example.ndkapplication D/MyCTestLog: a,i=8
2020-07-09 07:30:52.731 13150-13232/com.example.ndkapplication D/MyCTestLog: a,i=9
2020-07-09 07:30:52.731 13150-13233/com.example.ndkapplication D/MyCTestLog: b,i=0
2020-07-09 07:30:52.731 13150-13233/com.example.ndkapplication D/MyCTestLog: b,i=1
2020-07-09 07:30:52.731 13150-13233/com.example.ndkapplication D/MyCTestLog: b,i=2
2020-07-09 07:30:52.731 13150-13233/com.example.ndkapplication D/MyCTestLog: b,i=3
2020-07-09 07:30:52.731 13150-13233/com.example.ndkapplication D/MyCTestLog: b,i=4