jni中的线程, 同步以及生产者消费者模式

  • 编译环境centos6.×64

线程创建以及结束

http://www.runoob.com/cplusplus/cpp-multithreading.html

#include <pthread.h>
pthread_create (thread, attr, start_routine, arg) 

连接和分离线程

pthread_join (threadid, status) 
pthread_detach (threadid) 

pthread_join() 子程序阻碍调用程序,直到指定的 threadid 线程终止为止。

例子1


#include <unistd.h>
#include <pthread.h>

void* thr_fun(void* arg){
    char* no = (char*)arg;
    int i = 0;
    for(; i < 10; i++){
        printf("%s thread, i:%d\n",no,i);
        if(i==5){
            //线程退出(自杀)
            pthread_exit(2);
            //他杀pthread_cancel          
        }
    }   
    return 1;
}   


void main(){
    //线程的引用
    pthread_t tid;
    pthread_create(&tid,NULL,thr_fun,"线程1");
    void *rval;
    pthread_join(tid,&rval);
    printf("线程结束%d\n",rval);

}

代码意思,pthread_create开启了线程,当thr_fun遍历10次,当第5次的时候退出线程.

  • 编译命令: gcc test1.c -o main -lpthread

  • 执行 结果

[root@host threadDemo]# ./main
线程1 thread, i:0
线程1 thread, i:1
线程1 thread, i:2
线程1 thread, i:3
线程1 thread, i:4
线程1 thread, i:5
线程结束 2

例子2

多线程问题


#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <pthread.h>

int i=0;
void* thr_fun(void* arg){
        char* no = (char*)arg;

        for(; i < 10; i++){
                printf("%s thread, i:%d\n",no,i);
                sleep(1);
        }
        i=0;
        return 1;

}
void main(){
        //线程的引用
        pthread_t tid,tid2;
        pthread_create(&tid,NULL,thr_fun,"线程1");
        pthread_create(&tid2,NULL,thr_fun,"线程2");

        void *rval;
         pthread_join(tid,&rval);
         pthread_join(tid2,&rval);
        printf("线程结束 %d",rval);

}

编译出来main2 执行后 每隔一秒先打印线程2 然后打印i

可以看出 是两个线程抢占使用thr_fun 出现这种结果 .

如果我想每个线程单独打印i ,应该怎么做 : 同步

[root@host threadDemo]# gcc 02.c -o main2 -lpthread
[root@host threadDemo]# ls
02.c  main  main2  test1.c  thread01.c
[root@host threadDemo]# ./main2
线程2 thread, i:0
线程1 thread, i:0
线程2 thread, i:1
线程1 thread, i:2
线程2 thread, i:3
线程1 thread, i:4
线程2 thread, i:5
线程1 thread, i:6
线程2 thread, i:7
线程1 thread, i:8
线程2 thread, i:9
线程2 thread, i:1
线程2 thread, i:2
线程2 thread, i:3
线程2 thread, i:4
线程2 thread, i:5
线程2 thread, i:6
线程2 thread, i:7
线程2 thread, i:8
线程2 thread, i:9
线程结束 1

线程的同步

  • 现在的目的: 第一个线程全部输出完成后,第二个线程再去打印.

int pthread_mutex_init 是一条指令,是中断指令的标识。
该函数用于C函数的多线程编程中,互斥锁的初始化。
(类似 synchronized 作用)

int pthread_mutex_init(pthread_mutex_t *restrict mutex,
const pthread_mutexattr_t *restrict attr);
posix下抽象了一个锁类型的结构:ptread_mutex_t。通过对该结构的操作,来判断资源是否可以访问。
顾名思义,加锁(lock)后,别人就无法打开,只有当锁没有关闭(unlock)的时候才能访问资源。
即对象互斥锁的概念,来保证共享数据操作的完整性。每个对象都对应于一个可称为” 互斥锁” 的标记,
这个标记用来保证在任一时刻,只能有一个线程访问该对象。

参数一 创建一个锁
参数二指定了新建互斥锁的属性。如果参数attr为NULL,则使用默认的互斥锁属性,默认属性为快速互斥锁

  • PTHREAD_MUTEX_TIMED_NP,这是缺省值,也就是普通锁。当一个线程加锁以后,其余请求锁的线程将形成一个等待队列,并在解锁后按优先级获得锁。这种锁策略保证了资源分配的公平性。
  • PTHREAD_MUTEX_RECURSIVE_NP,嵌套锁,允许同一个线程对同一个锁成功获得多次,并通过多次unlock解锁。如果是不同线程请求,则在加锁线程解锁时重新竞争。
  • PTHREAD_MUTEX_ERRORCHECK_NP,检错锁,如果同一个线程请求同一个锁,则返回EDEADLK,否则与PTHREAD_MUTEX_TIMED_NP类型动作相同。这样就保证当不允许多次加锁时不会出现最简单情况下的死锁。
  • PTHREAD_MUTEX_ADAPTIVE_NP,适应锁,动作最简单的锁类型,仅等待解锁后重新竞争。

代码:

#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <pthread.h>
int i=0;
//锁对象
pthread_mutex_t mutex;
void* thr_fun(void* arg){

        char* no = (char*)arg;
       //加锁的代码块
        pthread_mutex_lock(&mutex);
        for(; i < 10; i++){
                printf("%s thread, i:%d\n",no,i);
               sleep(1);
        }
        //取消锁
        pthread_mutex_unlock(&mutex);
        i=0;
        return 1;
}


void main(){
        //互斥锁的初始化        
        pthread_mutex_init(&mutex,NULL);
        //线程初始化
        pthread_t tid1,tid2;
        pthread_create(&tid1,NULL,thr_fun,"线程1");
        pthread_create(&tid2,NULL,thr_fun,"线程2");

        void *rval;
        pthread_join(tid1,&rval);
        pthread_join(tid2,&rval);
        printf("线程结束%d\n",rval);
        //销毁锁
        pthread_mutex_destroy(&mutex);
}

打印结果:

[root@host threadDemo]# gcc 02.c -o main2 -lpthread
02.c: In function ‘thr_fun’:
02.c:20: warning: return makes pointer from integer without a cast
[root@host threadDemo]# ls
02.c  main  main2  test1.c  thread01.c
[root@host threadDemo]# ./main2
线程2 thread, i:0
线程2 thread, i:1
线程2 thread, i:2
线程2 thread, i:3
线程2 thread, i:4
线程2 thread, i:5
线程2 thread, i:6
线程2 thread, i:7
线程2 thread, i:8
线程2 thread, i:9
线程1 thread, i:0
线程1 thread, i:1
线程1 thread, i:2
线程1 thread, i:3
线程1 thread, i:4
线程1 thread, i:5
线程1 thread, i:6
线程1 thread, i:7
线程1 thread, i:8
线程1 thread, i:9
线程结束1

可以看到 先打印了线程二执行的输入 结束之后才打印线程一的输出.

生产者消费者

阻塞在条件变量上pthread_cond_wait

解除在条件变量上的阻塞pthread_cond_signal

https://blog.csdn.net/ffilman/article/details/4871920

#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <pthread.h>

//模拟 产品队列
int ready = 0;

//互斥锁
pthread_mutex_t mutex;

//条件变量 判断是否有产品
pthread_cond_t has_product;

//生产者
void* produce(void *arg){
        char* name = (char*)arg;
        for(;;) {
                //锁住
                pthread_mutex_lock(&mutex);
                ready++;//生产进入队列
                printf("%s  生产 %d \n",name,ready);
                //发送一条解锁消息
                pthread_cond_signal(&has_product);
                //解锁
                pthread_mutex_unlock(&mutex);
                sleep(3);
        }
}

//消费者
void* consumer(void* arg){
        char* name = (char*)arg;
        for(;;){
                //加锁
                pthread_mutex_lock(&mutex);
                //如果产品列表为空 继续等待, 因为有可能不止一个消费者
                while(ready==0){
                        printf("没有产品了,等待生产\n");
                        //等待
                        pthread_cond_wait(&has_product,&mutex);
                }
                //消费 出队列
                printf("%s 消费%d\n",name,ready);
                ready--;
                printf(" 当前产品%d\n",ready);
                //解锁
                pthread_mutex_unlock(&mutex);
                sleep(1);
        }
}

void main(){
        //互斥锁初始化
        pthread_mutex_init(&mutex,NULL);
        //条件变量初始化
        pthread_cond_init(&has_product,NULL);
        //线程的引用 这里三个 一个生产两个消费
        pthread_t tid1,tid2,tid3;
        pthread_create(&tid1,NULL,produce,"生产者1");
        pthread_create(&tid2,NULL,consumer,"消费者1");
        pthread_create(&tid3,NULL,consumer,"消费者2");

        printf("开启线程");
        void *rval;
        pthread_join(tid1,&rval);
        pthread_join(tid2,&rval);
        pthread_join(tid3,&rval);
        printf("线程结束%d\n",rval);
}


结果:

开启线程没有产品了,等待生产
没有产品了,等待生产
生产者1  生产 1 
消费者2 消费1
 当前产品0
没有产品了,等待生产
生产者1  生产 1 
消费者1 消费1
 当前产品0
没有产品了,等待生产
生产者1  生产 1 
消费者2 消费1
 当前产品0
没有产品了,等待生产
生产者1  生产 1 
消费者1 消费1
 当前产品0
没有产品了,等待生产
生产者1  生产 1 
消费者2 消费1
 当前产品0
没有产品了,等待生产
生产者1  生产 1 
消费者1 消费1
 当前产品0
没有产品了,等待生产

生产者消费者模式.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值