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

 

 

转载于:https://www.cnblogs.com/MMLoveMeMM/articles/3751515.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值