linux多线程服务器编程(全方面了解linux多线程服务)(11/13)

来源:国外服务器 在您之前已被浏览:1 次
导读:目前正在解读《linux多线程服务器编程(全方面了解linux多线程服务)(11/13)》的相关信息,《linux多线程服务器编程(全方面了解linux多线程服务)(11/13)》是由用户自行发布的知识型内容!下面请观看由(国外主机 - www.2bp.net)用户发布《linux多线程服务器编程(全方面了解linux多线程服务)(11/13)》的详细说明。
笨笨网美国主机,w ww.2 b p .n e t

8.线程取消

8.1线程取消函数接口

int pthread_cancel(pthread_t thread);

一个线程可以通过调用该函数向另一个线程发送取消请求。 这不是个阻塞型接口, 发出请求后, 函数就立刻返回了, 而不会等待目标线程退出之后才返回。

调用pthread_cancel时, 会向目标线程发送一个SIGCANCEL的信号, 该信号就是kill -l中消失的32号信号。

线程的默认取消状态是PTHREAD_CANCEL_ENABLE。即是可被取消的。

linux多线程服务器编程(全方面了解linux多线程服务)(11/13)


什么是取消点? 可通过man pthreads查看取消点

就是对于某些函数, 如果线程允许取消且取消类型是延迟取消, 并且线程也收到了取消请求, 那么当执行到这些函数的时候, 线程就可以退出了。

8.2线程取消带来的弊端

目标线程可能会持有互斥量、 信号量或其他类型的锁, 这时候如果收到取消请求, 并且取消类型是异步取消, 那么可能目标线程掌握的资源还没有来得及释放就被迫退出了, 这可能会给其他线程带来不可恢复的后果, 比如死锁(其他线程再也无法获得资源) 。

注意:

轻易不要调用pthread_cancel函数, 在外部杀死线程是很糟糕的做法,毕竟如果想通知目标线程退出, 还可以采取其他方法。

如果不得不允许线程取消, 那么在某些非常关键不容有失的代码区域, 暂时将线程设置成不可取消状态, 退出关键区域之后, 再恢复成可以取消的状态。

在非关键的区域, 也要将线程设置成延迟取消, 永远不要设置成异步取消。

8.2线程清理函数

假设遇到取消请求, 线程执行到了取消点, 却没有来得及做清理动作(如动态申请的内存没有释放, 申请的互斥量没有解锁等) , 可能会导致错误的产生, 比如死锁, 甚至是进程崩溃。

为了避免这种情况, 线程可以设置一个或多个清理函数, 线程取消或退出时,会自动执行这些清理函数, 以确保资源处于一致的状态。

如果线程被取消, 清理函数则会负责解锁操作。

void pthread_cleanup_push(void (*routine)(void *),void *arg);void pthread_cleanup_pop(int execute);

这两个函数必须同时出现, 并且属于同一个语法块。

何时会触发注册的清理函数:?

1、当线程的主函数是调用pthread_exit返回的, 清理函数总是会被执行。

2、当线程是被其他线程调用pthread_cancel取消的, 清理函数总是会被执行。

3、当线程的主函数是通过return返回的, 并且pthread_cleanup_pop的唯一参数execute是0时, 清理函数不会被执行.

4、线程的主函数是通过return返回的, 并且pthread_cleanup_pop的唯一参数execute是非零值时, 清理函数会执行一次。

代码:

#include #include #include #include #include #include #define NUMBER 2int g_bowl = 0;pthread_mutex_t mutex;//定义互斥锁void clean(void *arg){ printf("Clean up:%sn",(char*)arg); pthread_mutex_unlock(&mutex);//释放锁}void *WorkCancel(void *arg){ pthread_mutex_lock(&mutex); pthread_cleanup_push(clean,"clean up handler");//清除函数的push struct timespec t = {3,0};//取消点 nanosleep(&t,0); pthread_cleanup_pop(0);//清除 pthread_mutex_unlock(&mutex);}void *WorkWhile(void *arg){ sleep(5); pthread_mutex_lock(&mutex); printf("i get the mutexn");//若能拿到资源,则表示取消清理函数成功! pthread_mutex_unlock(&mutex); return NULL;}int main(){ pthread_t cons,prod; pthread_mutex_init(&mutex,NULL);//互斥锁初始化 int ret = pthread_create(&prod,NULL,WorkCancel,(void*)&g_bowl);//该线程拿到锁,然后挂掉 if(ret != 0) { perror("pthread_create"); return -1; } int ret1 = pthread_create(&cons,NULL,WorkWhile,(void*)&ret);//测试该线程是否可以拿到锁 if(ret1 != 0) { perror("pthread_create"); return -1; } pthread_cancel(prod);//取消该线程 pthread_join(prod,NULL);//线程等待 pthread_join(cons,NULL);//线程等待 pthread_mutex_destroy(&mutex);//销毁互斥锁 while(1) { sleep(1); } return 0;}

结果:只要拿到锁,就表明线程清理函数成功了。

linux多线程服务器编程(全方面了解linux多线程服务)(11/13)


笨笨网美国主机,w ww.2 b p .n e t
提醒:《linux多线程服务器编程(全方面了解linux多线程服务)(11/13)》最后刷新时间 2025-03-21 11:13:52,本站为公益型个人网站,仅供个人学习和记录信息,不进行任何商业性质的盈利。如果内容、图片资源失效或内容涉及侵权,请反馈至,我们会及时处理。本站只保证内容的可读性,无法保证真实性,《linux多线程服务器编程(全方面了解linux多线程服务)(11/13)》该内容的真实性请自行鉴别。