C语言多线程编程 死锁解析

摘要:
以下代码:#include #include #include pthread_ mutex _ tm;Void*runadd{int i=0;对于{pthread_mutex_lock(&m);printf;usleep;pthread-mutex_unlock(&mm);}};Void*runven{int i=0;对于{pthread _mutex_lock(&m解决方案:使用两个函数pthread_cleanup_pushpthread_cleanup_pop函数类似于atexit函数。注意:这不是一个函数,而是一个宏。voidpthread _ cleanup _ push;触发调用例程:exit()的条件被执行。

1.假设有两个线程

  A线程负责输出奇数。B线程负责输出偶数。

2.当A线程进入锁定状态是,主线程突然异常将A线程停止,这时将导致B线程也无法继续执行,处于死锁状态。如下代码:

#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
pthread_mutex_t m;

void *runodd(void *d)
{
        int i=0;

        for(i=1;;i+=2)
        {
                pthread_mutex_lock(&m);
                printf("奇数:%d
",i);
                usleep(100);
                pthread_mutex_unlock(&m);
        }
}
void *runeven(void *d)
{
        int i=0;
        for(i=0;;i+=2)
        {
                pthread_mutex_lock(&m);
                printf("偶数:%d
",i);
                usleep(100);
                pthread_mutex_unlock(&m);
        }
}
main()
{
        pthread_t todd,teven;
        pthread_mutex_init(&m,0);
        pthread_create(&todd,0,runodd,0);
        pthread_create(&teven,0,runeven,0);
        sleep(5);
        printf("外部强制停止todd线程
");
        pthread_cancel(todd);
        pthread_join(todd,(void**)0);
        pthread_join(teven,(void**)0);
        pthread_mutex_destroy(&m);
}

解决方法:
运用2个函数(其实是2个宏)

pthread_cleanup_push

pthread_cleanup_pop 这个对函数作用类似于atexit函数

注意:这不是函数而是宏。必须成对使用。

void pthread_cleanup_push(

void (*routine)(void *),//回调函数

void *arg //回调函数的参数

);

触发调用routine的条件:

  1. 执行了exit()。
  2. 执行了pthread_cancel()
  3. pthread_cleanup_pop(1);//参数必须是1
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
pthread_mutex_t m;
void handle(void *d)
{
        printf("退出后的调用!
");
        pthread_mutex_unlock(&m);
}
void *runodd(void *d)
{
        int i=0;

        for(i=1;;i+=2)
        {
                pthread_cleanup_push(handle,0);
                pthread_mutex_lock(&m);
                printf("奇数:%d
",i);
                usleep(100);
                pthread_mutex_unlock(&m);
                pthread_cleanup_pop(0);
        }
}
void *runeven(void *d)
{
        int i=0;
        for(i=0;;i+=2)
        {
                pthread_mutex_lock(&m);
                printf("偶数:%d
",i);
                usleep(100);
                pthread_mutex_unlock(&m);
        }
}

免责声明:文章转载自《C语言多线程编程 死锁解析》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇[转]web计时机制——performance对象JavaScript基础知识总结下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

python——多线程与线程锁

一、概念: 进程:对系统过来说,一个任务是一个进程; 线程:线程是包含在进程中。进程中,线程来工作,线程是最小的单位。一个进程可以启多个线程 二、进程和线程使用时的选择: 1.cpu密集型任务,用进程 #比如排序、计算的功能2.IO密集型任务,多线程 input Output #读写频繁,网络IO或者磁盘IO。浪费CPU比较少的用多线程3.如果需要读写也需...

Handler 机制(一)—— Handler的实现流程

   由于Android采用的是单线程模式,开发者无法在子线程中更新 UI,所以系统给我提供了 Handler 这个类来实现 UI 更新问题。本贴主要说明 Handler 的工作流程。 1. Handler 的作用 在Android为了保障线程安全,规定只能由主线程来更新UI信息。而在实际开发中,会经常遇到多个子线程都去操作UI信息的情况,那么就会导致U...

winform知识

控件相关 1.文本框/label高度 文本框Multiline属性,设为true就可以了。改完高度后再将此属性改回来,要不然多行文本框,按回去就去下一行了。 label的改autoSize属性,设为false就可以了。 2.控件中文字居中 TextAlign属性:MiddleCenter 3.颜色属性 直接输入 #xxxx 4.如何去掉button按钮的...

Oracle报 ORA-00054资源正忙的解决办法

来源于:http://www.cnblogs.com/loveLearning/p/3625544.html oracle之报错:ORA-00054: 资源正忙,要求指定 NOWAIT 问题如下: SQL> conn scott/tiger@vm_databaseConnected to Oracle Database 11g Enterprise...

JVM 内存布局及 GC 原理

“java 的内存布局以及 GC 原理”是 java 开发人员绕不开的话题,也是面试中常见的高频问题之一。 java 发展历史上出现过很多垃圾回收器,各有各的适应场景,很多网上的旧文章已经跟不上最新的变化。本文详细介绍了 java 的内存布局以及各种垃圾回收器的原理(包括最新的 ZGC),希望阅读完后,大家对这方面的知识不再陌生,有所收获,同时也欢迎大家留...

c# sleep 例子

using System; using System.Threading; public class arr { public static void Main() { //int[] arr; //arr = new int[5]; int luzi; for(luzi=1;luzi<10000;luzi++) { Console.WriteL...