Android NDK Pthreads Detailed use

Source: Internet
Author: User
Tags mutex

This pthread.h file can create sub-threads in the NDK environment and can control the threads to make mutually exclusive, wait, and destroy.

The reason to write this blog is that I want to write how to play video using FFmpeg, because I need to play audio and video at the same time, so I need to turn on threads and set up the relationship between producer and consumer.

All right, go straight to the whole.

1. Opening and destroying threads

The Pthread_create function can create a thread, the first parameter is a reference to a thread, the second is a thread's property, is generally null, a third is a function that runs on a thread, and a fourth is a parameter that runs a function to a thread

Pthread_create is an open thread, as long as the function thread runs, that is, the function represented by the third parameter is run.

pthread_t pthreads;pthread_create(&pthreads, NULL, threadFunc, (void *) "zzw");

Wait for the thread to complete and return parameters, this if the open thread only one can not write, but if there are multiple threads this must be written, do not write the words will only run the first thread

int retvalue;pthread_join(pthreads,(void**)&retvalue);if(retvalue!=0){    __android_log_print(ANDROID_LOG_ERROR,"hello","thread error occurred");}

Let's take a look at the thread run function, which he can get parameters and can end the thread prematurely

void threadfunc (void arg) {

char* str=(char*)arg;for(int i=0;i<3;i++){    __android_log_print(ANDROID_LOG_VERBOSE,"hello","i = %d arg = %s",i,str);    //线程自杀,需要返回参数    //pthread_exit((void*)2);    //线程他杀    //pthread_cancel()}return (void *) 0;

}

Complete example code

#include <jni.h>
#include <string>
#include <android/log.h>
#define LOGE (FORMAT,...) Android_log_print (Android_log_error, "LC XXX", format,##va_args__);

extern "C"
Jniexport jstring
Jnicall
Java_com_example_zth_ndkthread_mainactivity_stringfromjni (
JNIEnv Env,
Jobject/
This */) {
std::string Hello = "Hello from c + +";
Return Env->newstringutf (Hello.c_str ());
}

void threadfunc (void arg) {

char* str=(char*)arg;for(int i=0;i<3;i++){    __android_log_print(ANDROID_LOG_VERBOSE,"hello","i = %d arg = %s",i,str);    //线程自杀,需要返回参数    //pthread_exit((void*)2);    //线程他杀    //pthread_cancel()}return (void *) 0;

}

extern "C"
Jniexport void Jnicall
Java_com_example_zth_ndkthread_mainactivity_startnativethread (jnienv* env, Jobject thiz,jint count) {

pthread_t pthreads;pthread_create(&pthreads, NULL, threadFunc, (void *) "zzw");int retvalue;pthread_join(pthreads,(void**)&retvalue);if(retvalue!=0){    __android_log_print(ANDROID_LOG_ERROR,"hello","thread error occurred");}

}

2. Mutual exclusion Lock

A mutex is the ability to lock a piece of code so that the code cannot be executed again until it is unlocked.

Initialization

pthread_mutex_t pthread_mutex;if(pthread_mutex_init(&pthread_mutex,NULL)!=0)    return;

Pass the mutex to the thread run function when the thread is turned on

for(int i=0;i<count;i++){    pthread_create(&pthreads[i],NULL,threadFunc,&pthread_mutex);}

Let's take a look at the thread run function
Remove the mutex and lock it

pthread_mutex_t* pthread_mutex=(pthread_mutex_t*)arg;pthread_mutex_lock(pthread_mutex);

Then a section of code

for(int i=0;i<3;i++){    __android_log_print(ANDROID_LOG_VERBOSE,"hello","i = %d",i);}__android_log_print(ANDROID_LOG_VERBOSE,"hello","————————————");

Unlock

Pthread_mutex_unlock (Pthread_mutex);

Finally destroy the mutex lock

pthread_mutex_destroy(&pthread_mutex);

Run the following effect

03-02 14:25:58.346 10022-10077/com.example.zth.ndkthread v/hello:i = 0
03-02 14:25:58.346 10022-10077/com.example.zth.ndkthread v/hello:i = 1
03-02 14:25:58.346 10022-10077/com.example.zth.ndkthread v/hello:i = 2
03-02 14:25:58.346 10022-10077/com.example.zth.ndkthread V/hello:------------------------
03-02 14:25:58.346 10022-10078/com.example.zth.ndkthread v/hello:i = 0
03-02 14:25:58.346 10022-10078/com.example.zth.ndkthread v/hello:i = 1
03-02 14:25:58.346 10022-10078/com.example.zth.ndkthread v/hello:i = 2
03-02 14:25:58.346 10022-10078/com.example.zth.ndkthread V/hello:------------------------
03-02 14:25:58.347 10022-10079/com.example.zth.ndkthread v/hello:i = 0
03-02 14:25:58.347 10022-10079/com.example.zth.ndkthread v/hello:i = 1
03-02 14:25:58.347 10022-10079/com.example.zth.ndkthread v/hello:i = 2
03-02 14:25:58.347 10022-10079/com.example.zth.ndkthread V/hello: ————————————

What if we don't have a lock?

pthread_mutex_t* pthread_mutex=(pthread_mutex_t*)arg;

Pthread_mutex_lock (Pthread_mutex);
for (int i=0;i<3;i++) {
Android_log_print (android_log_verbose, "Hello", "I =%d", i);
}
Android_log_print (android_log_verbose, "Hello", "------------------------");
Pthread_mutex_unlock (Pthread_mutex);

The results are as follows

03-02 14:36:50.035 13815-13993/com.example.zth.ndkthread v/hello:i = 0
03-02 14:36:50.035 13815-13993/ Com.example.zth.ndkthread v/hello:i = 1
03-02 14:36:50.035 13815-13993/com.example.zth.ndkthread v/hello:i = 2
03-02 14:36:50.035 13815-13993/com.example.zth.ndkthread V/hello:------------------------
03-02 14:36:50.035 13815-13994/com.example.zth.ndkthread v/hello:i = 0
03-02 14:36:50.035 13815-13994/com.example.zth.ndkthread V/ hello:i = 1
03-02 14:36:50.035 13815-13994/com.example.zth.ndkthread v/hello:i = 2
03-02 14:36:50.035 13815-13995 /com.example.zth.ndkthread v/hello:i = 0
03-02 14:36:50.035 13815-13994/com.example.zth.ndkthread V/hello:------- -----------------
03-02 14:36:50.035 13815-13995/com.example.zth.ndkthread v/hello:i = 1
03-02 14:36:50.035 13815-13995/com.example.zth.ndkthread v/hello:i = 2
03-02 14:36:50.035 13815-13995/com.example.zth.ndkthread V/ Hello:------------------------

So a mutex is a thread that is done first, and then another thread.

Example code:

#include <jni.h>
#include <string>
#include <android/log.h>
#include "Pthread.h"
#define LOGE (FORMAT,...) Android_log_print (Android_log_error, "LC XXX", format,##va_args__);

extern "C"
Jniexport jstring
Jnicall
Java_com_example_zth_ndkthread_mainactivity_stringfromjni (
JNIEnv Env,
Jobject/
This */) {
std::string Hello = "Hello from c + +";
Return Env->newstringutf (Hello.c_str ());
}

void threadfunc (void arg) {

pthread_mutex_t* pthread_mutex=(pthread_mutex_t*)arg;pthread_mutex_lock(pthread_mutex);for(int i=0;i<3;i++){    __android_log_print(ANDROID_LOG_VERBOSE,"hello","i = %d",i);}__android_log_print(ANDROID_LOG_VERBOSE,"hello","------------------------");pthread_mutex_unlock(pthread_mutex);return (void *) 0;

}

extern "C"
Jniexport void Jnicall
Java_com_example_zth_ndkthread_mainactivity_startnativethread (jnienv* env, Jobject thiz,jint count) {

pthread_mutex_t pthread_mutex;if(pthread_mutex_init(&pthread_mutex,NULL)!=0)    return;pthread_t pthreads[count];for(int i=0;i<count;i++){    pthread_create(&pthreads[i],NULL,threadFunc,&pthread_mutex);}for(int i=0;i<count;i++){    int retvalue=0;    pthread_join(pthreads[i],(void**)&retvalue);    if(retvalue!=0){        __android_log_print(ANDROID_LOG_ERROR,"hello","thread error occurred");    }}pthread_mutex_destroy(&pthread_mutex);

}

3. Condition variables

The video decoding is drawn using the producer-consumer model. For example, the products produced by our producers are placed in a queue, and when the producer produces the product, it sends a signal to inform the consumer to consume

This condition variable can wake the thread to run

Initialization

Pthread_cond_init (&c,null);

Turn on the creator thread and the consumer thread

pthread_create(&thread_producer, NULL, produce, (void *) "producer");pthread_create(&thread_comsumer, NULL, comsume, (void *) "comsumer");

Cycle the production of products and then remind consumers

for(;;){    pthread_mutex_lock(&m);    productNum++;    __android_log_print(ANDROID_LOG_VERBOSE,"hello","i = %d",productNum);    pthread_cond_signal(&c);    pthread_mutex_unlock(&m);}

Consumer threads wait for a conditional variable reminder if there is no product, and if a product is consumed

    pthread_mutex_lock(&m);    while(productNum == 0){        pthread_cond_wait(&c,&m);    }    productNum--;    __android_log_print(ANDROID_LOG_VERBOSE,"hello","i = %d",productNum);    pthread_mutex_unlock(&m);

Note that the entire process of the generator and the consumer thread is under the mutex, executed in order one by one, so that the calculation of the global variable productnum is not wrong, and one thread executes pthread_cond_signal to trigger another thread to execute

Example code

#include <jni.h>
#include <string>
#include <android/log.h>
#include "Pthread.h"
#define LOGE (FORMAT,...) Android_log_print (Android_log_error, "LC XXX", format,##va_args__);

extern "C"
Jniexport jstring
Jnicall
Java_com_example_zth_ndkthread_mainactivity_stringfromjni (
JNIEnv Env,
Jobject/
This */) {
std::string Hello = "Hello from c + +";
Return Env->newstringutf (Hello.c_str ());
}

int productnum = 0;
pthread_mutex_t m;
pthread_cond_t C;

void produce (void arg) {
char no = (char) arg;
for (;;) {
Pthread_mutex_lock (&M);
productnum++;
__android_log_print (android_log_verbose, "Hello", "I =%d", productnum);
Pthread_cond_signal (&C);
Pthread_mutex_unlock (&M);

}

}

void comsume (void arg) {
char no = (char) arg;
for (;;) {
Pthread_mutex_lock (&M);
while (Productnum = = 0) {
Pthread_cond_wait (&C,&M);

    }    productNum--;    __android_log_print(ANDROID_LOG_VERBOSE,"hello","i = %d",productNum);    pthread_mutex_unlock(&m);}

}

extern "C"
Jniexport void Jnicall
Java_com_example_zth_ndkthread_mainactivity_startnativethread (jnienv* env, Jobject thiz,jint count) {

pthread_mutex_init(&m,NULL);pthread_cond_init(&c,NULL);pthread_t thread_producer;pthread_t thread_comsumer;pthread_create(&thread_producer, NULL, produce, (void *) "producer");pthread_create(&thread_comsumer, NULL, comsume, (void *) "comsumer");pthread_join(thread_producer,NULL);pthread_join(thread_comsumer,NULL);pthread_mutex_destroy(&m);pthread_cond_destroy(&c);

}

Reference articles

https://www.jianshu.com/p/453d12c16885

http://blog.csdn.net/lxmhuendan/article/details/11967593

Android NDK Pthreads Detailed use

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.