三个简单的例子,记录NDK中的POSIX-thread线程的常用用法。好记性不如烂笔头。
第一个例子,创建,退出,自杀,它杀。
#include
#include
#include
#include
void* pthread_run(void* arg){
char* no = (char*)arg;
int i = 0;
for(; i < 10; i++){
printf("%s , i:%d\n",no,i);
if(i==8){
//线程退出(自杀)
pthread_exit(2);
}
}
//pthread_exit(1);
return 1;
}
void main(){
pthread_t tid;
//线程的属性,NULL默认属性
pthread_create(&tid,NULL,pthread_run,"pthread-test1");
usleep(5000); // 睡眠5ms
pthread_cancel(tid);
//主动杀死pthread_cancel
void* rval;
//等待tid线程结束
//pthread_run 退出时return的值,作为rval的内容
pthread_join(tid,&rval);
printf("rval:%d\n",(int)rval);
}
pthread_cancel调用并不等待线程终止,它只提出请求。线程在取消请求(pthread_cancel)发出后会继续运行,直到到达某个取消点(CancellationPoint)。取消点是线程检查是否被取消并按照请求进行动作的一个位置。
所以一般cancel之后都要跟join
详细知识点:http://www.cnblogs.com/lijunamneg/archive/2013/01/25/2877211.html
第二个例子,线程安全,互斥锁,相当于java的synchronized代码块
#include
#include
#include
#include
int i = 0;
//互斥锁
pthread_mutex_t mtx;
void* pthread_run(void* arg){
//加锁
pthread_mtx_lock(&mtx);
char* no = (char*)arg;
printf("%s begin work.\n",no);
for(;i < 5; i++){
printf("%d\n",i);
sleep(1);
}
//解锁
pthread_mutex_unlock(&mtx);
}
void main(){
pthread_t tid1, tid2;
//初始化互斥锁
pthread_mutex_init(&mtx,NULL);
pthread_create(&tid1,NULL,pthread_run ,"pthread-test1");
pthread_create(&tid2,NULL,pthread_run,"pthread-test2");
//等待两个线程的返回
pthread_join(tid1,NULL);
pthread_join(tid2,NULL);
//销毁互斥锁
pthread_mutex_destroy(&mtx);
}
这个比较简单,主要是小心出现死锁现象,何为死锁?
N(N>2)个工作线程pthread1、2、3,大于1个以上的pthread_mutex_t 1 和 2。
当pthread1进入工作后先lock mtx1,然后一段时间后lock mtx2。
当pthread2进入工作后先lock mtx2,然后一段时间后lock mtx1。
此时就会出现pthread1一直等待mtx2,pthread2一直等待mtx1,pthread3~4~等其他线程就会完全工作不了。耗费机器资源。
详细知识:https://www.cnblogs.com/crunchyou/archive/2013/02/20/2918207.html
第三个,生产者消费者模式,条件变量,相当于java的wait / notify
#include
#include
#include
#include
//消费者数量
#define CONSUMER_NUM 2
//生产者数量
#define PRODUCER_NUM 1
//产品计数
int ready = 0;
//互斥锁
pthread_mutex_t mutex;
//条件变量
pthread_cond_t has_product;
pthread_t pids[CONSUMER_NUM+PRODUCER_NUM];
//生产
void* producer(void* arg){
int no = (int)arg;
//条件变量
for(;;){
pthread_mutex_lock(&mutex);
//往队列中添加产品
ready++;
printf("producer %d, produce product\n",no);
//fflush(NULL);
//通知消费者,有新的产品可以消费了
//会阻塞输出
pthread_cond_signal(&has_product);
printf("producer %d, singal\n",no);
pthread_mutex_unlock(&mutex);
sleep(1);
}
}
//消费者
void* consumer(void* arg){
int num = (int)arg;
for(;;){
pthread_mutex_lock(&mutex);
//while?
//superious wake ‘惊群效应’
while(ready==0){
//没有产品,继续等待
//1.阻塞等待has_product被唤醒
//2.释放互斥锁,pthread_mutex_unlock
//3.被唤醒时,解除阻塞,重新申请获得互斥锁pthread_mutex_lock
printf("%d consumer wait\n",num);
pthread_cond_wait(&has_product,&mutex);
}
//有产品,消费产品
ready--;
printf("%d consume product\n",num);
pthread_mutex_unlock(&mutex);
sleep(1);
}
}
void main(){
//初始化互斥锁和条件变量
pthread_mutex_init(&mutex,NULL);
pthread_cond_init(&has_product,NULL);
int i;
for(i=0; i
条件变量pthread_cond_t 必须是要和一个 pthread_mutex_t 配对使用,而且关于pthread_cond_t 的wait 和 signal 也要配对使用,因为单纯的wait没有signal会阻塞导致线程挂起,日志输出也会有影响。
详细知识点:https://www.cnblogs.com/zhx831/p/3543633.html