方法介绍
数据类型:
pthread_t:线程ID
pthread_attr_t:线程属性
操纵函数:
pthread_create():创建一个线程
pthread_exit():终止当前线程
pthread_cancel():中断另外一个线程的运行
pthread_join():阻塞当前的线程,直到另外一个线程运行结束
pthread_attr_init():初始化线程的属性
pthread_attr_setdetachstate():设置脱离状态的属性(决定这个线程在终止时是否可以被结合)
pthread_attr_getdetachstate():获取脱离状态的属性
pthread_attr_destroy():删除线程的属性
pthread_kill():向线程发送一个信号
同步函数:
用于 mutex 和条件变量
pthread_mutex_init() 初始化互斥锁
pthread_mutex_destroy() 删除互斥锁
pthread_mutex_lock():占有互斥锁(阻塞操作)
pthread_mutex_trylock():试图占有互斥锁(不阻塞操作)。即,当互斥锁空闲时,将占有该锁;否则,立即返回。
pthread_mutex_unlock(): 释放互斥锁
pthread_cond_init():初始化条件变量
pthread_cond_destroy():销毁条件变量
pthread_cond_signal(): 唤醒第一个调用pthread_cond_wait()而进入睡眠的线程
pthread_cond_wait(): 等待条件变量的特殊条件发生
Thread-local storage(或者以Pthreads术语,称作线程特有数据):
pthread_key_create(): 分配用于标识进程中线程特定数据的键
pthread_setspecific(): 为指定线程特定数据键设置线程特定绑定
pthread_getspecific(): 获取调用线程的键绑定,并将该绑定存储在 value 指向的位置中
pthread_key_delete(): 销毁现有线程特定数据键
pthread_attr_getschedparam();获取线程优先级
pthread_attr_setschedparam();设置线程优先级
工具函数:
pthread_equal(): 对两个线程的线程标识号进行比较
pthread_detach(): 分离线程
pthread_self(): 查询线程自身线程标识号
1、创建一个线程
这里的pthread_create(&tid,NULL,thr_fun,”1”); 就是创建一个id为tid的线程
之后编译生成一个可执行文件
gcc 01.c -o 01 -lpthread
之后执行这个可执行文件
发现他只打印了第一句话,这个时候不是子线程没执行,而是因为主线程没有等待子线程就已经结束了,程序都干掉了,线程还会存在吗,这个时候在里面睡眠以下就好了
再来执行一下
现在就好了
2、阻塞线程:pthread_join
刚才是因为睡眠了一秒,才执行了子线程,现在可以让他等待子线程结束了再往下走
执行
可以看到最后一行拿到了返回值1,这个时候我在中间把线程杀死
执行一下
会发现最后的返回值变成了pthread_exit中传入的参数
3、互斥锁
执行一下
会看到他是乱的,那怎么有顺序的执行呢
#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 < 5; i++){
printf("线程名:%s,i:%d\n",no,i);
sleep(1);
}
i = 0;
//解锁
pthread_mutex_unlock(&mutex);
}
void main(){
pthread_t tid1,tid2;
//初始化互斥锁
pthread_mutex_init(&mutex,NULL);
pthread_create(&tid1,NULL,thr_fun,"No1");
pthread_create(&tid2,NULL,thr_fun,"No2");
pthread_join(tid1,NULL);
pthread_join(tid2,NULL);
//销毁互斥锁
pthread_mutex_destroy(&mutex);
}
执行的结果是
总结:
pthread_mutex_t:互斥锁
pthread_mutex_lock(&mutex):加锁
pthread_mutex_unlock(&mutex):解锁
pthread_mutex_init(&mutex,NULL):初始化互斥锁
pthread_mutex_destroy(&mutex):销毁互斥锁
加锁之后就表示别的线程不能访问,只有解锁之后才能交给别的线程访问
4、生产者、消费者模式
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <pthread.h>
//消费者数量
#define CONSUMER_NUM 2
//生产者数量
#define PRODUCER_NUM 1
pthread_t pids[CONSUMER_NUM+PRODUCER_NUM];
//产品队列
int ready = 0;
//互斥锁
pthread_mutex_t mutex;
//条件变量
pthread_cond_t has_product;
//生产
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);
printf("init\n");
int i;
for(i=0; i<PRODUCER_NUM;i++){
//生产者线程
printf("%d\n",i);
pthread_create(&pids[i],NULL,producer,(void*)i);
}
for(i=0; i<CONSUMER_NUM;i++){
//消费者线程
pthread_create(&pids[PRODUCER_NUM+i],NULL,consumer,(void*)i);
}
//等待
sleep(10);
for(i=0; i<PRODUCER_NUM+CONSUMER_NUM;i++){
pthread_join(pids[i],NULL);
}
//销毁互斥锁和条件变量
pthread_mutex_destroy(&mutex);
pthread_cond_destroy(&has_product);
}
执行之后的结果
[root@iz2zefc73lz5afpo72um1nz thread]# ./003
init
0
1 consumer wait
producer 0,produce product
producer 0 ,singal
0 consume product
1 consumer wait
0 consumer wait
producer 0,produce product
producer 0 ,singal
1 consume product
producer 0,produce product
producer 0 ,singal
1 consume product
0 consumer wait
producer 0,produce product
producer 0 ,singal
1 consume product
0 consumer wait
producer 0,produce product
producer 0 ,singal
1 consume product
0 consumer wait
5、ubuntu上安装pthread手册
在ubuntu上安装pthread手册
apt-get install manpages-posix-dev
查看的时候使用
查看有哪些函数:man -k pthread
查看函数详细内容,比如查看pthread_create:man pthread_create
按q退出