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