linux c 调用java_Linux生产者消费者模型与C/C++子线程调用Java

生产者消费者模型

基于生产者和消费者的模型在编程中运用是较多。生产者是一个或者多个线程产生数据,消费者是另一个或者多个线程处理数据,内存缓冲区可以使用集合数组队列方式,主要是用来协调生产者和消费者之间的数据产生和消费平衡。关键是如何处理多线程之间的协作。

在这个模型中,内存缓冲区为空的时候消费者处于等待状态待生产者唤醒,当内存缓冲区满的时候,生产者处于等待状态待消费者唤醒。当内存缓冲区有产品没有达到最大容量时生产者和消费者是处于一个动态平衡状态。设计到多线程,保证数据的正确新所以就需要锁来保证。

#include

#include

#include

#include

#include

#include

pthread_t product_thread, consumer_thread;

pthread_mutex_t mutex;

pthread_cond_t condition;

std::queue product_queue;

bool is_exit = false;

/**

*生产者

*/

void *product(void *arg) {

__android_log_print(ANDROID_LOG_ERROR, "thread_demo", "%s", (char *) arg);

while (!is_exit) {

//加锁

pthread_mutex_lock(&mutex);

product_queue.push(1);

__android_log_print(ANDROID_LOG_ERROR, "thread_demo", "生产者生产产品%d", product_queue.size());

//通知消费者消费

pthread_cond_signal(&condition);

//释放锁

pthread_mutex_unlock(&mutex);

sleep(2);

}

return NULL;

}

/**

*消费者

*/

void *consumer(void *arg) {

__android_log_print(ANDROID_LOG_ERROR, "thread_demo", "%s", (char *) arg);

while (!is_exit) {

pthread_mutex_lock(&mutex);

if (!product_queue.empty()) {

product_queue.pop();

__android_log_print(ANDROID_LOG_ERROR, "thread_demo", "消费者消费产品%d", product_queue.size());

} else{

//等待生产者 阻塞 会把锁释放

__android_log_print(ANDROID_LOG_ERROR, "thread_demo", "消费者%s","等待生产者生产产品");

pthread_cond_wait(&condition, &mutex);

}

pthread_mutex_unlock(&mutex);

usleep(1000 * 500);

}

return NULL;

}

/**

* 生产者 消费者

*/

extern "C"

JNIEXPORT void JNICALL

Java_com_youyangbo_thread_MainActivity_productConsumer(JNIEnv *env, jobject instance) {

int i = 0;

for (; i < 10; ++i) {

product_queue.push(i);

}

//初始化锁

pthread_mutex_init(&mutex, NULL);

//初始化条件

pthread_cond_init(&condition, NULL);

//创建线程

pthread_create(&product_thread, NULL, product, (void *) "product");

pthread_create(&consumer_thread, NULL, consumer, (void *) "consumer");

//阻塞等待线程完毕

pthread_join(product_thread, NULL);

pthread_join(consumer_thread, NULL);

}

C/C++子线程调用java方法

C/C++与java之间的互相调用是要通过JNI来实现的,JNIEnv是与线程之间有关系的,不同的线程JNIEnv是不同的,当我们在c/c++层创建一个子线程要用到JNIEnv,这个子线程的JNIEnv如何得到呢?获取到JavaVM 然后通过JavaVM 调用AttachCurrentThread(JNIEnv** p_env, void* thr_args)来的到JNIEnv。JavaVM 怎么得到呢?在java调用native方法是会先执行JNI_OnLoad(JavaVM* vm, void* reserved),还需要注意一个细节就是获取MethodID不能够在子线程获取。需要放在主线程,创建 instance参数所引用对象的新全局引用 obj = env->NewGlobalRef(instance);

public class MainActivity extends AppCompatActivity {

static {

System.loadLibrary("native-lib");

}

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);

callLog();

}

public native void callLog();

public void loge() {

Log.e( "loge: ", "被c++子线程调用了");

}

}

#include

#include

#include

#include

JavaVM *java_vm;

jmethodID jmid;

jobject obj;

void *thread_callBack(void *arg) {

JNIEnv *env;

java_vm->AttachCurrentThread(&env, NULL);

if (!obj){

pthread_exit(0);

}

env->CallVoidMethod(obj, jmid);

java_vm->DetachCurrentThread();

return NULL;

}

extern "C"

JNIEXPORT void JNICALL

Java_com_youyangbo_thread_MainActivity_callLog(JNIEnv *env, jobject instance) {

obj = env->NewGlobalRef(instance);

jclass clz = env->GetObjectClass(obj);

jmid = env->GetMethodID(clz, "loge", "()V");

pthread_t pthread;

pthread_create(&pthread, NULL, thread_callBack, NULL);

pthread_join(pthread, NULL);

env->DeleteGlobalRef(obj);

}

extern "C"

JNIEXPORT jint JNICALL

JNI_OnLoad(JavaVM *vm, void *reserved) {

JNIEnv *env;

java_vm = vm;

if (vm->GetEnv((void **) &env, JNI_VERSION_1_6) != JNI_OK) {

return -1;

}

return JNI_VERSION_1_6;

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值