Android NDK JNI C++ <15> pthread mutex互斥


多線程的互斥和信號,主要是用來保護臨界區,即當有多個全局變量被多個線程可能同時訪問時,其中一個或者多個線程可能修改這個全局變量或者對象,導致另外一個正在訪問這個全局變量或者對象的線程出現數據突然變更,從而導致異常或者運算錯誤,為了避免這些情況,互斥和信號就被引入,但全局變量或者對象被調用時,將會被枷鎖保護起來,防止線程在調用過程中出現全局變量或者對象突然變更的情況,該線程用完了,就解鎖,另外的線程就可以接着使用了,大概是這么個道理.

步驟如下:

<1> : 新建一個Android工程,新建一個org的包,新建一個mutexClass.java.

 

<2> : 新建jni文件夾,onload.cpp,onload.h就不在這里show了,mutexclass.cpp如下:

#include <android/log.h>
#include <stdlib.h>
#include <stdio.h>
#include <assert.h>
#include <string.h>
#include <pthread.h>
#include <unistd.h>
#include "onload.h"

#define TAG "jni_thread"
#define LOGI(...) ((void)__android_log_print(ANDROID_LOG_INFO,TAG,__VA_ARGS__))
#define LOGW(...) ((void)__android_log_print(ANDROID_LOG_WARN,TAG,__VA_ARGS__))
#define LOGE(...) ((void)__android_log_print(ANDROID_LOG_ERROR,TAG,__VA_ARGS__))

namespace android {

pthread_mutex_t mutex1;

typedef struct {

    int age;
    double scores;

} ZONEDATA;

ZONEDATA criticaldata;

int cnd=0;

void native_init() {

}

void* func_mutex(void* arg) {

    int i;
    i = *(int *) arg;
//    LOGI("value i : %d", i);

    LOGI("value cnd : %d", cnd);

    pthread_mutex_lock(&mutex1);
    //operation global variables
    //change global variables value or attribution
    criticaldata.age = criticaldata.age + (cnd++);

    pthread_mutex_unlock(&mutex1);

    LOGI("cnt : %d age : %d >", (cnd-1), criticaldata.age);
    pthread_detach (pthread_self());
    pthread_exit((void *)0);

}

void* interupt_mutex(void* arg){

    int i;
    for(i=0;i<100;i++){
        cnd+=10;
        for(int j=0;j<100000;j++){
            ;
        }
    }

}

void mutex_thread() {

    pthread_attr_t attr;
    pthread_t pthread_id[5];
    pthread_t inter_t;
    int i;
    void* status;
    criticaldata.age = 100;
    criticaldata.scores = 12.0;

    pthread_mutex_init(&mutex1, NULL);

    pthread_attr_init(&attr);
    pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);

    pthread_create(&inter_t, NULL, &interupt_mutex, (void*) NULL);

    for (i = 0; i < 5; i++) {
        pthread_create(&pthread_id[i], &attr, &func_mutex, (void*) &i);
        LOGI("cnts : %d ages : %d >", i, criticaldata.age);
//        sleep(1);
    }

    pthread_attr_destroy(&attr);

    for (i = 0; i < 5; i++) {
        pthread_join(pthread_id[i], &status);

    }

    pthread_mutex_destroy(&mutex1);
    pthread_exit (NULL);

}

}

using namespace android;

JNINativeMethod gMethods[] = {

{ "nativeinit", "()V", (void*) native_init },

{ "mutexThread", "()V", (void*) mutex_thread } };

int register_android_mutex_jni_demo(JNIEnv *env) {

    return jniRegisterNativeMethods(env, "org/mutexClass", gMethods,
            sizeof(gMethods) / sizeof(gMethods[0]));

}

最好刪除pthread_exit (NULL);這一句.

<3> : 建立互斥的基本流程:

創建全局互斥對象->在主線程初始化互斥對象->創建要被保護的子線程->在子線程中調用全局變量之前,給互斥加上鎖lock->使用完全局變量后,記得釋放剛才那把鎖unlock->調用exit,釋放整個子線程.

<4> : 上面程序interupt_mutex是個干擾線程.

 

native thread exited without detaching這個異常的處理方式: http://blog.sina.com.cn/s/blog_8f9e665401013c9y.html

 信號的處理和mutex差不多,建立信號的基本流程都是一樣的,具體參見更詳細的說明documents : http://www.360doc.com/content/09/1130/00/79031_10038898.shtml

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM