#if 0
线程结束时清理函数
pthread_cleanup_push(),应该在线程开始的时候尽快执行初始化
pthread_cleanup_pop(),当遇到以下三种各件会自动调用该函数,不需要PC执行到此函数
1.调用pthread_exit()
2.响应取消请求例如pthread_cancel()
3.当pthread_cleanup_pop(arg)参数arg为非0时会线程退出时自动执行
如果没有以上三种情况,则不会执行;
#endif
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <semaphore.h>
sem_t sm0,sm1,sm2,sm3; //信号量定义 信号量为控制线程的执行
void ret_fn(void*str)//线程退出调用的回调函数
{
fputs(str,stdout);
}
void thread0(void)
{
if(0 != sem_wait(&sm0))//信号量进行阻塞
{
perror("sem_wait_0");
}
char *str = "thead0_return_FN is runing\n";
pthread_cleanup_push(ret_fn,str);//将回调函数入栈
fputs("thread0 is runing\n",stdout);
pthread_cleanup_pop(0);//将回调函数出栈,当遇到特定的条件会自动调用,不需要PC指到此才执行
return;
}
void thread1(void)
{
if(0 != sem_wait(&sm1))
{
perror("sem_wait_1");
}
char *str = "thead1_return_FN is runing\n";
pthread_cleanup_push(ret_fn,str);
fputs("thread1 is runing\n",stdout);
pthread_exit((void*)1);
pthread_cleanup_pop(0);
}
void thread2(void)
{
if(0 != sem_wait(&sm2))
{
perror("sem_wait_2");
}
char *str = "thead2_return_FN is runing\n";
pthread_cleanup_push(ret_fn,str);
fputs("thread2 is runing\n",stdout);
pthread_cleanup_pop(1);
fputs("线程结束才会执行pthread_cleanup_pop\n",stdout);//线程结束才会执行pthread_cleanup_pop
}
void thread3(void)
{
char *str = "thead3_return_FN is runing\n";
pthread_cleanup_push(ret_fn,str);
if(0 != sem_wait(&sm3))
{
perror("sem_wait_3");
}
fputs("thread3 is runing\n",stdout);
usleep(100);// 让主线程中的pthread_cancel可以执行
pthread_cleanup_pop(0);
}
int main(void)
{
pthread_t thd0,thd1,thd2,thd3;
if(0 != sem_init(&sm0,0,0))//初始化信号量
{
perror("sem_init_0");
exit(1);
}
if(0 != sem_init(&sm1,0,0))
{
perror("sem_init_0");
exit(1);
}
if(0 != sem_init(&sm2,0,0))
{
perror("sem_init_0");
exit(1);
}
if(0 != sem_init(&sm3,0,0))
{
perror("sem_init_0");
exit(1);
}
if(0 != pthread_create(&thd0,NULL,(void*)thread0,NULL))//创建线程
{
perror("pthread_create_0\n");
exit(1);
}
if(0 != pthread_create(&thd1,NULL,(void*)thread1,NULL))
{
perror("pthread_create_1\n");
exit(1);
}
if(0 != pthread_create(&thd2,NULL,(void*)thread2,NULL))
{
perror("pthread_create_2\n");
exit(1);
}
if(0 != pthread_create(&thd3,NULL,(void*)thread3,NULL))
{
perror("pthread_create_3\n");
exit(1);
}
unsigned char status = 0xF;//控制重复测试掩码
while(1)
{
fputs("请输入测试选项:0(没有调用回调函数),1(pthread_exit),2(pthread_cancel),3(参数非0 pthread_cleanup_pop)\n",stdout);
int in;
scanf("%d",&in);
switch(in)
{
case 0:
{
if(!(status & 0x1))
{
fputs("这个项目已测试过,请选择其它,谢谢\n",stdout);
break;
}
if(0 != sem_post(&sm0))//激活信号量,让子线程THD0继续执行
{
perror("sem_post_0\n");
}
status &= 0xe;
break;
}
case 1:
{
if(!(status & 0x2))
{
fputs("这个项目已测试过,请选择其它,谢谢\n",stdout);
break;
}
if(0 != sem_post(&sm1))
{
perror("sem_post_1\n");
}
status &= 0xc;
break;
}
case 2:
{
if(!(status & 0x4))
{
fputs("这个项目已测试过,请选择其它,谢谢\n",stdout);
break;
}
if(0 != sem_post(&sm2))
{
perror("sem_post_2\n");
}
status &= 0xb;
break;
}
case 3:
{
if(!(status & 0x8))
{
fputs("这个项目已测试过,请选择其它,谢谢\n",stdout);
break;
}
if(0 != sem_post(&sm3))
{
perror("sem_post_3\n");
}
pthread_cancel(thd3);
status &= 0x7;
break;
}
default: break;
}
sleep(1);
}
return 0;
}
线程结束时清理函数
pthread_cleanup_push(),应该在线程开始的时候尽快执行初始化
pthread_cleanup_pop(),当遇到以下三种各件会自动调用该函数,不需要PC执行到此函数
1.调用pthread_exit()
2.响应取消请求例如pthread_cancel()
3.当pthread_cleanup_pop(arg)参数arg为非0时会线程退出时自动执行
如果没有以上三种情况,则不会执行;
#endif
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <semaphore.h>
sem_t sm0,sm1,sm2,sm3; //信号量定义 信号量为控制线程的执行
void ret_fn(void*str)//线程退出调用的回调函数
{
fputs(str,stdout);
}
void thread0(void)
{
if(0 != sem_wait(&sm0))//信号量进行阻塞
{
perror("sem_wait_0");
}
char *str = "thead0_return_FN is runing\n";
pthread_cleanup_push(ret_fn,str);//将回调函数入栈
fputs("thread0 is runing\n",stdout);
pthread_cleanup_pop(0);//将回调函数出栈,当遇到特定的条件会自动调用,不需要PC指到此才执行
return;
}
void thread1(void)
{
if(0 != sem_wait(&sm1))
{
perror("sem_wait_1");
}
char *str = "thead1_return_FN is runing\n";
pthread_cleanup_push(ret_fn,str);
fputs("thread1 is runing\n",stdout);
pthread_exit((void*)1);
pthread_cleanup_pop(0);
}
void thread2(void)
{
if(0 != sem_wait(&sm2))
{
perror("sem_wait_2");
}
char *str = "thead2_return_FN is runing\n";
pthread_cleanup_push(ret_fn,str);
fputs("thread2 is runing\n",stdout);
pthread_cleanup_pop(1);
fputs("线程结束才会执行pthread_cleanup_pop\n",stdout);//线程结束才会执行pthread_cleanup_pop
}
void thread3(void)
{
char *str = "thead3_return_FN is runing\n";
pthread_cleanup_push(ret_fn,str);
if(0 != sem_wait(&sm3))
{
perror("sem_wait_3");
}
fputs("thread3 is runing\n",stdout);
usleep(100);// 让主线程中的pthread_cancel可以执行
pthread_cleanup_pop(0);
}
int main(void)
{
pthread_t thd0,thd1,thd2,thd3;
if(0 != sem_init(&sm0,0,0))//初始化信号量
{
perror("sem_init_0");
exit(1);
}
if(0 != sem_init(&sm1,0,0))
{
perror("sem_init_0");
exit(1);
}
if(0 != sem_init(&sm2,0,0))
{
perror("sem_init_0");
exit(1);
}
if(0 != sem_init(&sm3,0,0))
{
perror("sem_init_0");
exit(1);
}
if(0 != pthread_create(&thd0,NULL,(void*)thread0,NULL))//创建线程
{
perror("pthread_create_0\n");
exit(1);
}
if(0 != pthread_create(&thd1,NULL,(void*)thread1,NULL))
{
perror("pthread_create_1\n");
exit(1);
}
if(0 != pthread_create(&thd2,NULL,(void*)thread2,NULL))
{
perror("pthread_create_2\n");
exit(1);
}
if(0 != pthread_create(&thd3,NULL,(void*)thread3,NULL))
{
perror("pthread_create_3\n");
exit(1);
}
unsigned char status = 0xF;//控制重复测试掩码
while(1)
{
fputs("请输入测试选项:0(没有调用回调函数),1(pthread_exit),2(pthread_cancel),3(参数非0 pthread_cleanup_pop)\n",stdout);
int in;
scanf("%d",&in);
switch(in)
{
case 0:
{
if(!(status & 0x1))
{
fputs("这个项目已测试过,请选择其它,谢谢\n",stdout);
break;
}
if(0 != sem_post(&sm0))//激活信号量,让子线程THD0继续执行
{
perror("sem_post_0\n");
}
status &= 0xe;
break;
}
case 1:
{
if(!(status & 0x2))
{
fputs("这个项目已测试过,请选择其它,谢谢\n",stdout);
break;
}
if(0 != sem_post(&sm1))
{
perror("sem_post_1\n");
}
status &= 0xc;
break;
}
case 2:
{
if(!(status & 0x4))
{
fputs("这个项目已测试过,请选择其它,谢谢\n",stdout);
break;
}
if(0 != sem_post(&sm2))
{
perror("sem_post_2\n");
}
status &= 0xb;
break;
}
case 3:
{
if(!(status & 0x8))
{
fputs("这个项目已测试过,请选择其它,谢谢\n",stdout);
break;
}
if(0 != sem_post(&sm3))
{
perror("sem_post_3\n");
}
pthread_cancel(thd3);
status &= 0x7;
break;
}
default: break;
}
sleep(1);
}
return 0;
}