由 tpp.c:63: __pthread_tpp_change_priority failed 引发的思考

2024-04-08 09:18

本文主要是介绍由 tpp.c:63: __pthread_tpp_change_priority failed 引发的思考,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

早上在测试一个程序的时候,同事发现了我们的程序出现了 tpp.c:63: __pthread_tpp_change_priority failed的错误报告。当时同事查了这方面的资料,发现是线程互斥锁(pthread_mutex_t)的缘故,并假设了出错的原因。关于这个我们还讨论了一阵。自己有些地方想不明白,于是向同事要了一些链接看了看。

因为这一段程序是我写的,所以想把自己出错的原因找到。Google了一下,找到了一些解释(见注释1)。

下边的这张图就是自己使用mutex的程序结构:


按照自己的理解,两个线程会交互运行。当时同事说不是。在这一点我们有争执。但是查过了一些资料,发现这样确实存在不是交互运行的情况。

于是自己在自己的PC和ARM平台上做了测试。

测试如下:

代码:                                                  

#include <stdio.h>           
#include <pthread.h>
#include <string.h>

pthread_mutex_t   sMutex;

void * test_pthread1(void * arg)
{
    while(1)
    {  
        pthread_mutex_lock(&sMutex);
        sleep(1);
        printf("%s: %d\n", __func__, __LINE__);
        pthread_mutex_unlock(&sMutex);
#ifdef T_SLEEP
       usleep(1);
#endif
    }  
}

void * test_pthread2(void * arg)
{
    while(1)
    {           pthread_mutex_lock(&sMutex);
        sleep(1);                                                              
        printf("%s: %d\n", __func__, __LINE__);
        pthread_mutex_unlock(&sMutex);
#ifdef  T_SLEEP
       usleep(1);
#endif
    }
}

int main(int arg, char **argv)
{    pthread_t  sPthread1;
    pthread_t  sPthread2;
    pthread_mutexattr_t  sTemp;

#ifdef  SET_ATTRUBITE
    pthread_mutexattr_init(&sTemp);
    pthread_mutexattr_settype(&sTemp, PTHREAD_MUTEX_RECURSIVE_NP);
    pthread_mutex_init(&sMutex, &sTemp);
#else
    pthread_mutex_init(&sMutex, NULL);
#endif 

    pthread_create(&sPthread1, NULL, test_pthread1, NULL);
    pthread_create(&sPthread2, NULL, test_pthread2, NULL);

    pthread_join(sPthread1, NULL);
    pthread_join(sPthread2, NULL);

QUIT:
    return 0;
}

嵌入式软硬件平台:
系统:
Linux version 2.6.32.20 (root@slax) (gcc version 4.2.3) #562 Fri Jun 15 12:21:42
CST 2012
CPU:
Processor       : ARM926EJ-S rev 5 (v5l)
BogoMIPS        : 66.15
Features        : swp half fastmult edsp java
CPU implementer : 0x41
CPU architecture: 5TEJ
CPU variant     : 0x0
CPU part        : 0x926
CPU revision    : 5

Hardware        : Atmel AT91SAM9260-EK
Revision        : 0000
Serial          : 0000000000000000
GCC version:
Using built-in specs.
Target: arm-none-linux-gnueabi
Configured with: /scratch/paul/arm/src/gcc-4.2/configure --build=i686-pc-linux-gnu --host=i686-pc-linux-gnu --target=arm-none-linux-gnueabi --enable-shared --enable-threads --disable-libmudflap --disable-libssp --disable-libgomp --disable-libstdcxx-pch --with-gnu-as --with-gnu-ld --prefix=/opt/codesourcery --enable-languages=c,c++ --enable-symvers=gnu --enable-__cxa_atexit --with-versuffix=CodeSourcery Sourcery G++ Lite 2007q1-10 --with-pkgversion=CodeSourcery Sourcery G++ Lite 2007q1-10 --with-bugurl=https://support.codesourcery.com/GNUToolchain/ --disable-nls --with-sysroot=/opt/codesourcery/arm-none-linux-gnueabi/libc --with-build-sysroot=/scratch/paul/arm/install/arm-none-linux-gnueabi/libc --enable-poison-system-directories --with-build-time-tools=/scratch/paul/arm/install/arm-none-linux-gnueabi/bin --with-build-time-tools=/scratch/paul/arm/install/arm-none-linux-gnueabi/bin
Thread model: posix
gcc version 4.2.0 20070413 (prerelease) (CodeSourcery Sourcery G++ Lite 2007q1-10)
Libc version:
GNU C Library stable release version 2.7, by Roland McGrath et al.
Copyright (C) 2007 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.
There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A
PARTICULAR PURPOSE.
Compiled by GNU CC version 4.2.3.
Compiled on a Linux >>2.6.24.4<< system on 2008-04-22.
Available extensions:
        crypt add-on version 2.1 by Michael Glad and others
        Native POSIX Threads Library by Ulrich Drepper et al
        Support for some architectures added on, not maintained in glibc core.
        BIND-8.2.3-T5B
For bug reporting instructions, please see:
<http://www.gnu.org/software/libc/bugs.html>.
PC软硬件平台:
系统:
Linux version 2.6.27.5-117.fc10.i686 (mockbuild@x86-7.fedora.phx.redhat.com) (gcc version 4.3.2 20081105 (Red Hat 4.3.2-7) (GCC) ) #1 SMP Tue Nov 18 12:19:59 EST 2008
CPU:
processor     : 0
vendor_id     : GenuineIntel
cpu family     : 6
model          : 22
model name     : Intel(R) Celeron(R) CPU          420  @ 1.60GHz
stepping     : 1
cpu MHz          : 1595.996
cache size     : 512 KB
fdiv_bug     : no
hlt_bug          : no
f00f_bug     : no
coma_bug     : no
fpu          : yes
fpu_exception     : yes
cpuid level     : 10
wp          : yes
flags          : fpu vme de pse tsc msr pae mce cx8 apic mtrr pge mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss nx constant_tsc up arch_perfmon pebs bts pni ssse3
bogomips     : 3191.99
clflush size     : 64
power management:
Gcc:
使用内建 specs。
目标:i386-redhat-linux
配置为:../configure --prefix=/usr --mandir=/usr/share/man --infodir=/usr/share/info --with-bugurl=http://bugzilla.redhat.com/bugzilla --enable-bootstrap --enable-shared --enable-threads=posix --enable-checking=release --with-system-zlib --enable-__cxa_atexit --disable-libunwind-exceptions --enable-languages=c,c++,objc,obj-c++,java,fortran,ada --enable-java-awt=gtk --disable-dssi --enable-plugin --with-java-home=/usr/lib/jvm/java-1.5.0-gcj-1.5.0.0/jre --enable-libgcj-multifile --enable-java-maintainer-mode --with-ecj-jar=/usr/share/java/eclipse-ecj.jar --disable-libjava-multilib --with-cpu=generic --build=i386-redhat-linux
线程模型:posix
gcc 版本 4.3.2 20081105 (Red Hat 4.3.2-7) (GCC) 
Libc version:
GNU C Library stable release version 2.9, by Roland McGrath et al.
Copyright (C) 2008 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.
There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A
PARTICULAR PURPOSE.
Compiled by GNU CC version 4.3.2 20081105 (Red Hat 4.3.2-7).
Compiled on a Linux >>2.6.18-92.1.10.el5<< system on 2008-11-13.
Available extensions:
     The C stubs add-on version 2.1.2.
     crypt add-on version 2.1 by Michael Glad and others
     GNU Libidn by Simon Josefsson
     Native POSIX Threads Library by Ulrich Drepper et al
     BIND-8.2.3-T5B
     RT using linux kernel aio
For bug reporting instructions, please see:
<http://www.gnu.org/software/libc/bugs.html>.

互斥锁双线程测试:
没有设置宏定义的时候
ARM平台:
root@Vancount:tmp# ./arm_test_mutex
test_pthread2: 26
test_pthread2: 26
test_pthread2: 26
test_pthread2: 26
test_pthread2: 26
test_pthread2: 26
PC平台:
[tt@vacount lin]$ ./test_mutex
test_pthread1: 14
test_pthread2: 26
test_pthread1: 14
test_pthread2: 26
test_pthread1: 14

设置宏定义 SET_ATTRIBUTE
#define SET_ATTRIBUTE
ARM平台:
root@Vancount:tmp# ./arm_test_mutex
test_pthread2: 26
test_pthread2: 26
test_pthread2: 26
test_pthread2: 26
test_pthread2: 26

PC平台:
[tt@vacount lin]$ ./test_mutex
test_pthread1: 14
test_pthread2: 26
test_pthread1: 14
test_pthread2: 26
test_pthread1: 14
test_pthread2: 26

设置宏定义 T_SLEEP
#define T_SLEEP
ARM平台:
root@Vancount:tmp# ./arm_test_mutex
test_pthread2: 26
test_pthread1: 14
test_pthread2: 26
test_pthread1: 14
test_pthread2: 26
test_pthread1: 14

PC平台:
[tt@vacount lin]$ ./test_mutex
test_pthread1: 14
test_pthread1: 14
test_pthread2: 26
test_pthread1: 14
test_pthread2: 26
test_pthread1: 14
test_pthread2: 26
test_pthread1: 14
test_pthread2: 26
(同时对于信号量也进行了测试,信号量的测试结果同互斥锁)

发现这里PC平台上,和ARM平台上的多线程运行结果有很大的不同。在PC上从第一个运行的线程来看,是先创建的线程先运行;而ARM平台上是后创建的线程先运行。这里不知道是否是因为GCC版本不同造成的。同时关于线程间的切换可以看到,在ARM平台上如果在解锁后不调用usleep(),两个线程只有一个线程在运行。

对于不同平台的程序测试要注意!

在单核CPU下,Linux的多线程切换,有时候并不是和我们想象的那样。

tpp.c下出错的源代码片段(完整见注):

61:   assert (new_prio == -1
62:          || (new_prio >= __sched_fifo_min_prio
63:              && new_prio <= __sched_fifo_max_prio));
64:   assert (previous_prio == -1
65:          || (previous_prio >= __sched_fifo_min_prio
66:              && previous_prio <= __sched_fifo_max_prio));
在有一篇帖子中看到作者的调试记录,发现是在63行处,是new_prio的值太大了,导致assert出错。这里是NPTL线程库中的函数出现了问题。

看到解决方案是设置mutex的属性,由默认的快速互斥锁修改为递归互斥锁就可以解决这个问题。

> The initialisation of the mutex is being done as follows:
>
> ---
> pthread_mutexattr_t mutexattr;
>
Just guessing: no pthread_mutexattr_init()!> // Set the mutex as a recursive mutex
> pthread_mutexattr_settype(&mutexattr, PTHREAD_MUTEX_RECURSIVE_NP);

(……)


注1:

几个链接:

http://sourceware.org/ml/libc-help/2008-05/msg00071.html
问题的具体描述。
http://sourceware.org/ml/libc-help/2008-05/msg00072.html
http://sourceware.org/bugzilla/show_bug.cgi?id=3610
问题的解答。
上边的帖子中提到,是因为mutex的属性问题,默认的mutex属性是fast性。多次重复加锁可能出问题。所以如果修改成递归属性,则会避免这个问题。
http://topic.csdn.net/u/20100317/10/ffb0994d-ea2d-49b4-94c6-ecf8aef1ca31.html
关于互斥锁的一个讨论。
http://www.xxlinux.com/linux/article/development/soft/20090424/16485.html
Linux多线程编程的一个挺好的帖子
http://sources.redhat.com/cgi-bin/cvsweb.cgi/libc/nptl/tpp.c?annotate=1.1.2.2&cvsroot=glibc
tpp.c源代码网址,tpp.c是Libc中NPTL(Native POSIX Thread Library)的一个文件。

这篇关于由 tpp.c:63: __pthread_tpp_change_priority failed 引发的思考的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/885171

相关文章

【编程底层思考】垃圾收集机制,GC算法,垃圾收集器类型概述

Java的垃圾收集(Garbage Collection,GC)机制是Java语言的一大特色,它负责自动管理内存的回收,释放不再使用的对象所占用的内存。以下是对Java垃圾收集机制的详细介绍: 一、垃圾收集机制概述: 对象存活判断:垃圾收集器定期检查堆内存中的对象,判断哪些对象是“垃圾”,即不再被任何引用链直接或间接引用的对象。内存回收:将判断为垃圾的对象占用的内存进行回收,以便重新使用。

fzu 2277 Change 线段树

Problem 2277 Change Time Limit: 2000 mSec    Memory Limit : 262144 KB  Problem Description There is a rooted tree with n nodes, number from 1-n. Root’s number is 1.Each node has a value ai.

android java.io.IOException: open failed: ENOENT (No such file or directory)-api23+权限受权

问题描述 在安卓上,清单明明已经受权了读写文件权限,但偏偏就是创建不了目录和文件 调用mkdirs()总是返回false. <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/><uses-permission android:name="android.permission.READ_E

UserWarning: mkl-service package failed to import

安装完成anaconda,并设置了两个环境变量  之后再控制台运行python环境,输入import numpy as np,提示错误 D:\InstallFolder\Anaconda3\lib\site-packages\numpy\__init__.py:143: UserWarning: mkl-service package failed to import, therefore

Python安装llama库出错“metadata-generation-failed”

Python安装llama库出错“metadata-generation-failed” 1. 安装llama库时出错2. 定位问题1. 去官网下载llama包 2.修改配置文件2.1 解压文件2.2 修改配置文件 3. 本地安装文件 1. 安装llama库时出错 2. 定位问题 根据查到的资料,发现时llama包中的execfile函数已经被下线了,需要我们手动修改代码后

时间序列|change point detection

change point detection 被称为变点检测,其基本定义是在一个序列或过程中,当某个统计特性(分布类型、分布参数)在某时间点受系统性因素而非偶然因素影响发生变化,我们就称该时间点为变点。变点识别即利用统计量或统计方法或机器学习方法将该变点位置估计出来。 Change Point Detection的类型 online 指连续观察某一随机过程,监测到变点时停止检验,不运用到

【编程底层思考】详解Java的JUC多线程并发编程底层组件AQS的作用及原理

Java中的AbstractQueuedSynchronizer(简称AQS)是位于java.util.concurrent.locks包中的一个核心组件,用于构建锁和其他同步器。AQS为实现依赖于FIFO(先进先出)等待队列的阻塞锁和相关同步器提供了一套高效、可扩展的框架。 一、AQS的作用 统一同步状态管理:AQS提供了一个int类型的成员变量state,用于表示同步状态。子类可以根据自己

674 - Coin Change

一道很水的DP,但我做的时候也很费劲,由于存在面值为1的时候,所以所有面额都至少有1种方法。 推导出状态方程就是 dp(V,step) += dp(V - i * coin[step],step - 1); 其中V为当前的面值,coin[step]为硬币的面额,递归边界,如果step == 0(也就是递归到硬币面额为1的时候,返回1); #include<cstdio>#include<

Typora配置PicGo时,提示Failed to fetch

Typora配置PicGo时,提示Failed to fetch 两者配置的端口不一致造成的 打开Typora,选择文件-偏好设置-图像-验证图片上传选项,点击验证图片上传选项 会提示错误:Failed to fetch,此时可以发现typora中设置的上传端口为36677 打开PigGo,选择PicGo设置-设置server,会发现监听端口为36678 修改监听接口为366

一道算法题引发的动态内存管理的思考

在做PKU2762时,需要建邻接表。 于是按部就班写了下面一个插入边到邻接表中的函数: const int VMAX = 1010;typedef struct Graph{int vex;Graph* next;}Graph;Graph ArcGraph[VMAX];void insert(int u, int v){Graph* t = new Graph;Graph*