1.函数 (三个 )
//1.pthread_join() 与wait 的功能相似 函数的功能: 等待另外一个线程的结束
//2.pthread_cancel 取消线程的执行 (取消执行的是传入的线程号)
//3.pthread_exit() 线程退出函数 与 获得线程的状态的函数一起用(pthread_join)
函数:pthread_join
头文件: #include<pthread.h>
函数原型:int pthread_join( pthread_t tid, void **status );
函数功能:pthread_join() 会阻塞调用它的线程,直到参数 tid 指定的线程结束。 tid 指定的线程必须在当前进程中,且必须是非分离的。 status 接收指定线程终止时的返回状态码。 不能有多个线程等待同一个线程终止,否则返回错误码 ESRCH ,当 pthread_join() 返回时,终止线程占用的堆栈等资源已被回收。 返
回值:成功返回 0
函数:pthread_cancel ()
头文件:pthread.h
原型:int pthread_cancel( pthread_t thread );
参数:thread 为所要取消的线程
返回值:成功返回0,非0表示不成功
功能补充:一线程调用pthread_cancel函数向另一线程的发送一个取消信号,
pthread_cancel并不能结束其它进程,
一般使用了pthread_cancel之后再调用pthread_join
pthread_exit与pthread_cancel的区别: pthread_exit用于当前线程退出,而pthread_cancel是当前线程取消另一线程的执行
函数:pthread_exit
头文件:pthread.h
原型:void pthread_exit(void * value_ptr);
参数:value_ptr 线程返回值指针
代码:(注意编译的时候 加上 -pthread 或者 -lpthread)
比如说: gcc 11.c -pthread -o 11
/************************************************************************************************************************************************************************************************************************
*文件名:
*作 者:She001
*时 间:
*版 本:
*作 用:pthread_join 函数的使用
****************************************************************************************************************************************************************************************************************************/
#include<stdio.h>
#include<string.h>
#include<math.h>
#include<stdlib.h>
#include<stdbool.h>
#include<time.h>
#include<unistd.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<errno.h>
#include<sys/wait.h>
#include<a.out.h>
#include<signal.h>
#include<stdarg.h>
#include<sys/socket.h>
#include<utime.h>
#include<sys/utsname.h>
#include<sys/times.h>
#include<sys/un.h>
#include<ctype.h>
#include<dirent.h>
#include<sys/time.h>
#include<sys/resource.h>
#include<syslog.h>
#include<pthread.h>
//1.pthread_join() 与wait 的功能相似 函数的功能: 等待另外一个线程的结束
//2.pthread_cancel 取消线程的执行 (取消执行的是传入的线程号)
//3.pthread_exit() 线程退出函数 与获得线程的状态的函数一起用
void * pthread_fun1(void *arg)//创建线程的函数
{
printf("this is %s %d %ld start \n",__func__,getpid(),pthread_self());
for(int i=0;i<10;i++)
{
printf("this is pthread_join test\n");
sleep(1);
}
printf("this is %s %d %ld end \n",__func__,getpid(),pthread_self());
pthread_exit((void *)1);//线程退出函数: 常量强转成指针
//return NULL;
}
int main(int argc,char *argv[])
{
printf("this is %s %d %ld start \n",__func__,getpid(),pthread_self());
pthread_t tid =0;
pthread_create(&tid,NULL,pthread_fun1,NULL);
sleep(2);
pthread_cancel(tid); //取消线程的执行
//pthread_join(tid,NULL); //不接受子线程的退出状态
//void *ret;
//pthread_join(tid,&ret); //接受子线程的退出状态
//printf("this exit status is %lu\n",(long unsigned int )ret);
//printf("this is %s %d %ld end \n",__func__,getpid(),pthread_self());
return 0;
}
程序功能:1.多线程抢占实验 : 主线程+3个线程 输出顺序是抢占的
2.多线程对公共的数据的访问,共享的
代码:(注意编译的时候 加上 -pthread 或者 -lpthread)
比如说: gcc 11.c -pthread -o 11
/************************************************************************************************************************************************************************************************************************
*文件名:
*作 者:She001
*时 间:
*版 本:
*作 用:
1.多线程抢占实验 : 主线程+3个线程 输出顺序是抢占的
2.多线程对公共的数据的访问,共享的
****************************************************************************************************************************************************************************************************************************/
#include<stdio.h>
#include<string.h>
#include<math.h>
#include<stdlib.h>
#include<stdbool.h>
#include<time.h>
#include<unistd.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<errno.h>
#include<sys/wait.h>
#include<a.out.h>
#include<signal.h>
#include<stdarg.h>
#include<sys/socket.h>
#include<utime.h>
#include<sys/utsname.h>
#include<sys/times.h>
#include<sys/un.h>
#include<ctype.h>
#include<dirent.h>
#include<sys/time.h>
#include<sys/resource.h>
#include<syslog.h>
#include<pthread.h>
int num=100;
void * pthread_fun1(void *arg)//创建线程的函数
{
printf("this is %s %d %ld start \n",__func__,getpid(),pthread_self());
for(int i=0;i<5;i++)
{
num+=1;
printf("1111111 :%d\n",num);
sleep(1);
}
printf("this is %s %d %ld end \n",__func__,getpid(),pthread_self());
}
void * pthread_fun2(void *arg)//创建线程的函数
{
printf("this is %s %d %ld start \n",__func__,getpid(),pthread_self());
for(int i=0;i<5;i++)
{
num-=2;
printf("22222222 :%d \n",num);
sleep(1);
}
printf("this is %s %d %ld end \n",__func__,getpid(),pthread_self());
}
void * pthread_fun3(void *arg)//创建线程的函数
{
printf("this is %s %d %ld start \n",__func__,getpid(),pthread_self());
for(int i=0;i<5;i++)
{
num+=3;
printf("333333333 :%d\n",num);
sleep(1);
}
printf("this is %s %d %ld end \n",__func__,getpid(),pthread_self());
}
int main(int argc,char *argv[])
{
printf("this is %s %d %ld start \n",__func__,getpid(),pthread_self());
pthread_t tid1 =0;
pthread_t tid2 =0;
pthread_t tid3 =0;
pthread_create(&tid1,NULL,pthread_fun1,NULL);
pthread_create(&tid2,NULL,pthread_fun2,NULL);
pthread_create(&tid3,NULL,pthread_fun3,NULL);
pthread_join(tid1,NULL); //不接受子线程的退出状态
pthread_join(tid2,NULL); //不接受子线程的退出状态
pthread_join(tid3,NULL); //不接受子线程的退出状态
printf("this is %s %d %ld end \n",__func__,getpid(),pthread_self());
return 0;
}
//线程创建 锁的函数 pthread_mutex_init()
//线程加锁 的函数 pthread_mutex_lock()
//线程解锁 的函数 pthread_mutex_unlock();
//线程的摧毁锁的函数 pthread_mutex_destroy();
//pthread_mutex_trylock—测试锁
头文件:pthread.h
函数原型: int pthread_mutex_init (pthread_mutex_t* mutex,const pthread_mutexattr_t* mutexattr); 函数参数: mutex:互斥锁。
Mutexattr :锁的类型 PTHREAD_MUTEX_INITIALIZER 创建快速互斥锁。 PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP 创建递归互斥锁。 PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP 创建检错互斥锁。
函数返回值:成功:0;出错:-1
头文件:pthread.h
原型: int pthread_mutex_lock(pthread_mutex_t *mutex);
参数:mutex互斥id
返回值:成功返回0,不成功返回-1 功能补充:如果指定的互斥id已经被锁住那么呼叫线程在互斥id完全解锁前将一直处于挂起状态,否则将锁住互斥体
堵塞的函数!!!!!!!!!!
头文件:pthread.h
原型:int pthread_mutex_trylock(pthread_mutex_t *mutex);
参数:mutex互斥id
返回值:成功返回0,不成功返回-1,如果已经被其线程上锁则返回EBUSY(在errno.h中);
功能:如果指定的互斥id已经被锁住那么将直接返回一个错误,通过判断此错误来进行不同的处理,测试完之后会加锁
不会堵塞的函数!!!!!!!!
头文件:pthread.h
原型: int pthread_mutex_unlock(pthread_mutex_t *mutex);
参数:mutex互斥id
返回值:成功返回0,不成功返回-1
头文件:pthread.h
原型: int pthread_mutex_destroy(pthread_mutex_t *mutex);
参数:mutex互斥id
返回值:成功返回0,不成功返回-1
程序功能: 抢占输出的时候 上锁 保护数据安全
1.多线程抢占实验 : 主线程+3个线程 输出顺序是抢占的
2.多线程对公共的数据的访问,共享的
3.对公共化数据上锁,互斥锁
代码:
/************************************************************************************************************************************************************************************************************************
*文件名:
*作 者:She001
*时 间:
*版 本:
*作 用:
1.多线程抢占实验 : 主线程+3个线程 输出顺序是抢占的
2.多线程对公共的数据的访问,共享的
3.对公共化数据上锁,互斥锁
****************************************************************************************************************************************************************************************************************************/
#include<stdio.h>
#include<string.h>
#include<math.h>
#include<stdlib.h>
#include<stdbool.h>
#include<time.h>
#include<unistd.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<errno.h>
#include<sys/wait.h>
#include<a.out.h>
#include<signal.h>
#include<stdarg.h>
#include<sys/socket.h>
#include<utime.h>
#include<sys/utsname.h>
#include<sys/times.h>
#include<sys/un.h>
#include<ctype.h>
#include<dirent.h>
#include<sys/time.h>
#include<sys/resource.h>
#include<syslog.h>
#include<pthread.h>
//线程创建 锁的函数 pthread_mutex_init()
//线程加锁 的函数 pthread_mutex_lock()
//线程解锁 的函数 pthread_mutex_unlock();
//线程的摧毁锁的函数 pthread_mutex_destroy();
//
//
//使用的步骤 (锁的状态为结构体)
//1.创建锁
//2.初始化锁
//3.上锁
//4.读写操作
//5.解锁
//6.销毁锁
int main(int argc,char *argv[])
{
//1.创建锁
pthread_mutex_t mutex =PTHREAD_MUTEX_INITIALIZER;
//2.初始化锁
if(pthread_mutex_init(&mutex,NULL)<0)
{
perror("pthrrad_mutex_init error\n");
return -1;
}
else
{
printf("pthread_mutex_init ok !\n");
}
//3.上锁
if(pthread_mutex_lock(&mutex)<0)//上锁
{
perror("pthread_mutex_lock error\n");
return -2;
}
else
{
printf("pthread_mutex_lock ok!\n");
}
int a;
#if 0
a = pthread_mutex_unlock(&mutex); //解锁
printf("a=%d\n",a);
if(!a)
{
printf("ulock ok!\n");
}
else
{
perror("unlock error!\n");
}
#endif
//下面这个函数 已经上锁的话 会返回-1
//没有上锁的话 ,会返回0 并且给你上锁
//测试函数 pthread_mutex_trylock 注意这里没有上锁后 函数会给你上锁
while(pthread_mutex_trylock(&mutex))
{
perror("trylock error\n");
sleep(1);
}
//4.读写操作
//5.解锁
a = pthread_mutex_unlock(&mutex); //解锁
printf("a=%d\n",a);
if(!a)
{
printf("ulock ok!\n");
}
else
{
perror("unlock error!\n");
}
//6.销毁锁
int b=pthread_mutex_destroy(&mutex);
if(!b)
{
printf("destroy ok!\n");
}
else
{
printf("destroy error!\n");
}
return 0;
}
测试练习
程序 功能: 在函数中实现 线程加锁解锁的功能
代码:
/************************************************************************************************************************************************************************************************************************
*文件名:
*作 者:She001
*时 间:
*版 本:
*作 用:
1.多线程抢占实验 : 主线程+3个线程 输出顺序是抢占的
2.多线程对公共的数据的访问,共享的
3.对公共化数据上锁,互斥锁
****************************************************************************************************************************************************************************************************************************/
#include<stdio.h>
#include<string.h>
#include<math.h>
#include<stdlib.h>
#include<stdbool.h>
#include<time.h>
#include<unistd.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<errno.h>
#include<sys/wait.h>
#include<a.out.h>
#include<signal.h>
#include<stdarg.h>
#include<sys/socket.h>
#include<utime.h>
#include<sys/utsname.h>
#include<sys/times.h>
#include<sys/un.h>
#include<ctype.h>
#include<dirent.h>
#include<sys/time.h>
#include<sys/resource.h>
#include<syslog.h>
#include<pthread.h>
//线程创建 锁的函数 pthread_mutex_init()
//线程加锁 的函数 pthread_mutex_lock()
//线程解锁 的函数 pthread_mutex_unlock();
//线程的摧毁锁的函数 pthread_mutex_destroy();
//
//
//使用的步骤 (锁的状态为结构体)
//1.创建锁
//2.初始化锁
//3.上锁
//4.读写操作
//5.解锁
//6.销毁锁
//程序的功能实现了每个操作的时候上锁
int num=100;
//1.创建锁 申请互斥锁
pthread_mutex_t mutex =PTHREAD_MUTEX_INITIALIZER;
void * pthread_fun1(void *arg)//创建线程的函数
{
while(pthread_mutex_trylock(&mutex))
{
perror("fun1 trylock error\n");
sleep(1);
}
int a;
printf("this is %s %d %ld start \n",__func__,getpid(),pthread_self());
for(int i=0;i<5;i++)
{
num+=1;
printf("1111111 :%d\n",num);
sleep(1);
}
printf("this is %s %d %ld end \n",__func__,getpid(),pthread_self());
#if 1
a = pthread_mutex_unlock(&mutex); //解锁
printf("a=%d\n",a);
if(!a)
{
printf("fun1 ulock ok!\n");
}
else
{
perror("fun1 unlock error!\n");
}
#endif
}
void * pthread_fun2(void *arg)//创建线程的函数
{
while(pthread_mutex_trylock(&mutex))
{
perror("fun2 trylock error\n");
sleep(1);
}
printf("this is %s %d %ld start \n",__func__,getpid(),pthread_self());
for(int i=0;i<5;i++)
{
num-=2;
printf("22222222 :%d \n",num);
sleep(1);
}
printf("this is %s %d %ld end \n",__func__,getpid(),pthread_self());
int a = pthread_mutex_unlock(&mutex); //解锁
printf("a=%d\n",a);
if(!a)
{
printf("fun2 ulock ok!\n");
}
else
{
perror("fun2 unlock error!\n");
}
}
void * pthread_fun3(void *arg)//创建线程的函数
{
while(pthread_mutex_trylock(&mutex))
{
perror("fun3 trylock error\n");
sleep(1);
}
printf("this is %s %d %ld start \n",__func__,getpid(),pthread_self());
for(int i=0;i<5;i++)
{
num+=3;
printf("333333333 :%d\n",num);
sleep(1);
}
printf("this is %s %d %ld end \n",__func__,getpid(),pthread_self());
int a = pthread_mutex_unlock(&mutex); //解锁
printf("a=%d\n",a);
if(!a)
{
printf("fun3 ulock ok!\n");
}
else
{
perror("fun3 unlock error!\n");
}
}
int main(int argc,char *argv[])
{
//2.初始化锁
if(pthread_mutex_init(&mutex,NULL)<0)
{
perror("pthrrad_mutex_init error\n");
return -1;
}
else
{
printf("pthread_mutex_init ok !\n");
}
printf("this is %s %d %ld start \n",__func__,getpid(),pthread_self());
pthread_t tid1 =0;
pthread_t tid2 =0;
pthread_t tid3 =0;
pthread_create(&tid1,NULL,pthread_fun1,NULL);
pthread_create(&tid2,NULL,pthread_fun2,NULL);
pthread_create(&tid3,NULL,pthread_fun3,NULL);
/*
//下面这个函数 已经上锁的话 会返回-1
//没有上锁的话 ,会返回0 并且给你上锁
//测试函数 pthread_mutex_trylock 注意这里没有上锁后 函数会给你上锁
while(pthread_mutex_trylock(&mutex))
{
perror("trylock error\n");
sleep(1);
}
*/
pthread_join(tid1,NULL); //不接受子线程的退出状态
pthread_join(tid2,NULL); //不接受子线程的退出状态
pthread_join(tid3,NULL); //不接受子线程的退出状态
//6.销毁锁
int b=pthread_mutex_destroy(&mutex);
if(!b)
{
printf("destroy ok!\n");
}
else
{
printf("destroy error!\n");
}
printf("this is %s %d %ld end \n",__func__,getpid(),pthread_self());
return 0;
}
线程唤醒功能的函数:pthread_cond_wait
pthread_cond_signal
pthread_cond_init
pthread_cond_init--初始化条件变量
头文件:pthread.h
原型:int pthread_cond_init(pthread_cond_t *cond, pthread_condattr_t*cond_attr);
参数:使用 cond_attr 指定的属性初始化条件变量 cond,当 cond_attr 为 NULL 时,使用缺省的属性。LinuxThreads 实现条件变量不支持属性,因此 cond_attr 参数实际被忽略
返回值: 在执行成功时,所有条件变量函数都返回 0,错误时返回非零的错误代码
注意:pthread_cond_t 类型的变量也可以用 PTHREAD_COND_INITIALIZER 常量进行静态初始化。
pthread_cond_signal--启动线程
头文件:pthread.h
原型:int pthread_cond_signal(pthread_cond_t *cond);
参数:cond为条件变量,初始化了的条件变量
返回值:在执行成功时,所有条件变量函数都返回 0,错误时返回非零的错误代码 功能补充:使在条件变量上等待的线程中的一个线程重新开始。如果没有等待的线程,则什么也不做。如果有多个线程在等待该条件,只有一个能重启动,但不能指定哪一个
pthread_cond_wait--自动解锁互斥量并等待条件变量触发
原型: int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex);
参数:自动解锁互斥量(如同执行了 pthread__mutex_unlock),并等待条件变量触发。这时线程挂起,不占用 CPU 时间,直到条件变量被触发。在调用 pthread_cond_wait 之前,应用程序必须加锁互斥量。pthread_cond_wait 函数返回前,自动重新对互斥量加锁(如同执行了 pthread_mutex_lock)。
返回值:在执行成功时,所有条件变量函数都返回 0,错误时返回非零的错误代码
pthread_cond_broadcast--重启动等待该条件变量的所有线程
头文件:pthread.h
原型:int pthread_cond_broadcast(pthread_cond_t *cond);
参数:cond为条件变量,初始化了的条件变量
返回值:在执行成功时,所有条件变量函数都返回 0,错误时返回非零的错误代码 功能补充: 重启动等待该条件变量的所有线程。如果没有等待的线程,则什么也不做。
pthread_cond_timedwait--自动解锁互斥量并等待条件变量触发
原型:int pthread_cond_timedwait(pthread_cond_t *cond, pthread_mutex_t *mutex, const struct timespec *abstime);
参数:cond为条件变量,mutex为互斥锁,abstime 参数指定一个绝对时间,时间原点与 time 相同
返回值:在执行成功时,所有条件变量函数都返回 0,错误时返回非零的错误代码
pthread_cond_destroy--销毁一个条件变量
原型:int pthread_cond_destroy(pthread_cond_t *cond);
参数:cond为条件变量
返回值:在执行成功时,所有条件变量函数都返回 0,错误时返回非零的错误代码
功能补充:pthread_cond_destroy 销毁一个条件变量,释放它拥有的资源。进入 pthread_cond_destroy 之前,必须没有在该条件变量上等待的线程。在 LinuxThreads 的实现中,条件变量不联结资源,除检查有没有等待的线程外,pthread_cond_destroy 实际上什么也不做。
注意:条件变量函数不是异步信号安全的,不应当在信号处理程序中进行调用。特别要注意,如果在信号处理程序中调用 pthread_cond_signal 或 pthread_cond_boardcast 函数,可能导致调用线程死锁。
代码:
/************************************************************************************************************************************************************************************************************************
*文件名:
*作 者:She001
*时 间:
*版 本:
*作 用:
****************************************************************************************************************************************************************************************************************************/
#include<stdio.h>
#include<unistd.h>
#include<pthread.h>
static pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
//一个线程等待,另一个线程唤醒。
//写一个线程1等待,线程2发送信号。
//子线程等待5s后向主线程发送信号,让线程继续运行。
void* thread_fun(void* arg)
{
printf("%s : start\n",__func__);
//sleep(10);
for(int i=1;i<=10;i++)
{
printf("+++++++++++++++++++++++++++\n");
sleep(1);
}
pthread_cond_signal(&cond);
//signal 唤醒一个 broadcast唤醒所有。
printf("%s end\n",__func__);
return NULL;
}
int main()
{
//分析执行流程。
pthread_t tid;
//初始化立即条件变量
pthread_cond_init(&cond,NULL);
pthread_mutex_init(&mutex,NULL);
//
pthread_create(&tid,NULL,thread_fun,NULL);
printf("%s : start\n",__func__);
//在主线程中等待,在子线程中唤醒。
//转让时间片,让子线程先运行。
//处于等待的线程
pthread_cond_wait(&cond,&mutex);//主线程开始等待
//还是有一种顺序在。
printf("main : do some thing to num \n");
sleep(1);//等待线程的结束
printf("%s : end\n",__func__);
pthread_cond_destroy(&cond);//销毁条件变量
pthread_mutex_destroy(&mutex);//销毁互斥锁
return 0;
}