pthread_cond_wait执行失败

2024-05-07 05:48
文章标签 执行 失败 wait pthread cond

本文主要是介绍pthread_cond_wait执行失败,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

Printf("execute result:%d",pthread_cond_wait(&reply_cond, &reply_mutex));

执行没有返回结果,日志也没有打印

查询linux doc查到如下结果:

Description

The pthread_cond_timedwait() and pthread_cond_wait() functions shall block on a condition variable. They shall be called withmutex locked by the calling thread or undefined behavior results.

These functions atomically release mutex and cause the calling thread to block on the condition variablecond; atomically here means "atomically with respect to access by another thread to the mutex and then the condition variable". That is, if another thread is able to acquire the mutex after the about-to-block thread has released it, then a subsequent call topthread_cond_broadcast() orpthread_cond_signal() in that thread shall behave as if it were issued after the about-to-block thread has blocked.

Upon successful return, the mutex shall have been locked and shall be owned by the calling thread.

When using condition variables there is always a Boolean predicate involving shared variables associated with each condition wait that is true if the thread should proceed. Spurious wakeups from thepthread_cond_timedwait() orpthread_cond_wait() functions may occur. Since the return frompthread_cond_timedwait() orpthread_cond_wait() does not imply anything about the value of this predicate, the predicate should be re-evaluated upon such return.

The effect of using more than one mutex for concurrent pthread_cond_timedwait() orpthread_cond_wait() operations on the same condition variable is undefined; that is, a condition variable becomes bound to a unique mutex when a thread waits on the condition variable, and this (dynamic) binding shall end when the wait returns.

A condition wait (whether timed or not) is a cancellation point. When the cancelability enable state of a thread is set to PTHREAD_CANCEL_DEFERRED, a side effect of acting upon a cancellation request while in a condition wait is that the mutex is (in effect) re-acquired before calling the first cancellation cleanup handler. The effect is as if the thread were unblocked, allowed to execute up to the point of returning from the call topthread_cond_timedwait() orpthread_cond_wait(), but at that point notices the cancellation request and instead of returning to the caller ofpthread_cond_timedwait() orpthread_cond_wait(), starts the thread cancellation activities, which includes calling cancellation cleanup handlers.

A thread that has been unblocked because it has been canceled while blocked in a call topthread_cond_timedwait() orpthread_cond_wait() shall not consume any condition signal that may be directed concurrently at the condition variable if there are other threads blocked on the condition variable.

The pthread_cond_timedwait() function shall be equivalent to pthread_cond_wait(), except that an error is returned if the absolute time specified byabstime passes (that is, system time equals or exceedsabstime) before the conditioncond is signaled or broadcasted, or if the absolute time specified byabstime has already been passed at the time of the call.

If the Clock Selection option is supported, the condition variable shall have a clock attribute which specifies the clock that shall be used to measure the time specified by theabstime argument. When such timeouts occur,pthread_cond_timedwait() shall nonetheless release and re-acquire the mutex referenced bymutex. Thepthread_cond_timedwait() function is also a cancellation point.

If a signal is delivered to a thread waiting for a condition variable, upon return from the signal handler the thread resumes waiting for the condition variable as if it was not interrupted, or it shall return zero due to spurious wakeup.

Return Value

Except in the case of [ETIMEDOUT], all these error checks shall act as if they were performed immediately at the beginning of processing for the function and shall cause an error return, in effect, prior to modifying the state of the mutex specified bymutex or the condition variable specified by cond.

Upon successful completion, a value of zero shall be returned; otherwise, an error number shall be returned to indicate the error.

Errors

The pthread_cond_timedwait() function shall fail if:

ETIMEDOUT
The time specified by abstime to pthread_cond_timedwait() has passed.

The pthread_cond_timedwait() and pthread_cond_wait() functions may fail if:

EINVAL
The value specified by cond, mutex, or abstime is invalid.
EINVAL
Different mutexes were supplied for concurrent pthread_cond_timedwait() or pthread_cond_wait() operations on the same condition variable.
EPERM
The mutex was not owned by the current thread at the time of the call.

These functions shall not return an error code of [EINTR].

查询源码:

pthread.h

int pthread_cond_broadcast(pthread_cond_t*) __nonnull((1));
int pthread_cond_destroy(pthread_cond_t*) __nonnull((1));
int pthread_cond_init(pthread_cond_t*, const pthread_condattr_t*) __nonnull((1));
int pthread_cond_signal(pthread_cond_t*) __nonnull((1));
int pthread_cond_timedwait(pthread_cond_t*, pthread_mutex_t*, const struct timespec*) __nonnull((1, 2, 3));
int pthread_cond_wait(pthread_cond_t*, pthread_mutex_t*) __nonnull((1, 2));

pthread_cond.cpp
int pthread_cond_broadcast(pthread_cond_t* cond) {return __pthread_cond_pulse(cond, INT_MAX);
}int pthread_cond_signal(pthread_cond_t* cond) {return __pthread_cond_pulse(cond, 1);
}int pthread_cond_wait(pthread_cond_t* cond, pthread_mutex_t* mutex) {return __pthread_cond_timedwait(cond, mutex, NULL, COND_GET_CLOCK(cond->value));
}int pthread_cond_timedwait(pthread_cond_t *cond, pthread_mutex_t * mutex, const timespec *abstime) {return __pthread_cond_timedwait(cond, mutex, abstime, COND_GET_CLOCK(cond->value));
}

__LIBC_HIDDEN__
int __pthread_cond_timedwait(pthread_cond_t* cond, pthread_mutex_t* mutex, const timespec* abstime, clockid_t clock) {timespec ts;timespec* tsp;if (abstime != NULL) {if (__timespec_from_absolute(&ts, abstime, clock) < 0) {//注释1return ETIMEDOUT;}tsp = &ts;} else {tsp = NULL;}return __pthread_cond_timedwait_relative(cond, mutex, tsp);
}

__LIBC_HIDDEN__
int __pthread_cond_timedwait_relative(pthread_cond_t* cond, pthread_mutex_t* mutex, const timespec* reltime) {int old_value = cond->value;pthread_mutex_unlock(mutex);int status = __futex_wait_ex(&cond->value, COND_IS_SHARED(cond->value), old_value, reltime);pthread_mutex_lock(mutex);if (status == -ETIMEDOUT) {return ETIMEDOUT;}return 0;
}
没有返回值的问题应该出在这里,可能是:
1.pthread_mutex_unlock(mutex);处,解锁没有成功,导致别的线程无法获得锁,刚开始在我的问题代码中pthread_cond_signal前确实无法获得锁;
2.__futex_wait_ex一直没有接收到条件变量的通知,一直在等待;
3.pthread_mutex_lock(mutex);处,别的线程已经锁住,无法继续执行。
在我的问题代码去掉获锁解锁后,pthread_cond_signal后pthread_cond_wait执行不成功,2和3的可能也是存在的。

bionic_futex.h
static inline int __futex_wake_ex(volatile void* ftx, bool shared, int count) {return __futex(ftx, shared ? FUTEX_WAKE : FUTEX_WAKE_PRIVATE, count, NULL);
}
static inline __always_inline int __futex(volatile void* ftx, int op, int value, const struct timespec* timeout) {// Our generated syscall assembler sets errno, but our callers (pthread functions) don't want to.int saved_errno = errno;int result = syscall(__NR_futex, ftx, op, value, timeout);if (__predict_false(result == -1)) {//注释2result = -errno;errno = saved_errno;}return result;
}
syscall.h
#ifndef _SYS_SYSCALL_H_
#define _SYS_SYSCALL_H_#include <errno.h>
#include <sys/cdefs.h>
#include <sys/types.h>
#include <asm/unistd.h>#include <sys/glibc-syscalls.h> /* glibc-compatible SYS_* aliases for our __NR_* names. */__BEGIN_DECLSlong syscall(long number, ...);__END_DECLS#endif

syscall是间接系统调用
查询linux doc:

NAME  top

       syscall - indirect system call

SYNOPSIS        top

       #define _GNU_SOURCE         /* See feature_test_macros(7) */#include <unistd.h>#include <sys/syscall.h>   /* For SYS_xxx definitions */long syscall(long number, ...);

DESCRIPTION        top

       syscall() is a small library function that invokes the system callwhose assembly language interface has the specified number with thespecified arguments.  Employing syscall() is useful, for example,when invoking a system call that has no wrapper function in the Clibrary.syscall() saves CPU registers before making the system call, restoresthe registers upon return from the system call, and stores any errorcode returned by the system call in errno(3) if an error occurs.Symbolic constants for system call numbers can be found in the headerfile <sys/syscall.h>.

RETURN VALUE        top

       The return value is defined by the system call being invoked.  Ingeneral, a 0 return value indicates success.  A -1 return valueindicates an error, and an error code is stored in errno.
syscall() 执行一个系统调用,根据指定的参数number和所有系统调用的汇编语言接口来确定调用哪个系统调用。
系统调用所使用的符号常量可以在头文件<sys/syscall.h>里面找到。

syscall(__NR_futex, ftx, op, value, timeout)中的__NR_futex可以在android5.1\bionic\libc\include\sys\glibc-syscalls.h中找到:
#define SYS_futex __NR_futex
在不同的平台值不同,例如在android5.1\bionic\libc\kernel\uapi\asm-x86\asm\unistd_64.h中:
/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
#define __NR_futex 202
#define __NR_sched_setaffinity 203
#define __NR_sched_getaffinity 204
#define __NR_set_thread_area 205




注释1:__timespec_from_absolute在pthread_internals.cpp定义

// Initialize 'ts' with the difference between 'abstime' and the current time
// according to 'clock'. Returns -1 if abstime already expired, or 0 otherwise.
int __timespec_from_absolute(timespec* ts, const timespec* abstime, clockid_t clock) {clock_gettime(clock, ts);ts->tv_sec  = abstime->tv_sec - ts->tv_sec;ts->tv_nsec = abstime->tv_nsec - ts->tv_nsec;if (ts->tv_nsec < 0) {ts->tv_sec--;ts->tv_nsec += 1000000000;}if ((ts->tv_nsec < 0) || (ts->tv_sec < 0)) {return -1;}return 0;
}

注释2:__predict_false在cdefs.h定义

#if __GNUC_PREREQ(2, 96)
#define __predict_true(exp) __builtin_expect((exp) != 0, 1)
#define __predict_false(exp) __builtin_expect((exp) != 0, 0)
#else
#define __predict_true(exp) (exp)
#define __predict_false(exp) (exp)
#endif



这篇关于pthread_cond_wait执行失败的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



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

相关文章

SpringBoot项目整合Netty启动失败的常见错误总结

《SpringBoot项目整合Netty启动失败的常见错误总结》本文总结了SpringBoot集成Netty时常见的8类问题及解决方案,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参... 目录一、端口冲突问题1. Tomcat与Netty端口冲突二、主线程被阻塞问题1. Netty启动阻

SpringBoot整合Kafka启动失败的常见错误问题总结(推荐)

《SpringBoot整合Kafka启动失败的常见错误问题总结(推荐)》本文总结了SpringBoot项目整合Kafka启动失败的常见错误,包括Kafka服务器连接问题、序列化配置错误、依赖配置问题、... 目录一、Kafka服务器连接问题1. Kafka服务器无法连接2. 开发环境与生产环境网络不通二、序

MyBatis Plus中执行原生SQL语句方法常见方案

《MyBatisPlus中执行原生SQL语句方法常见方案》MyBatisPlus提供了多种执行原生SQL语句的方法,包括使用SqlRunner工具类、@Select注解和XML映射文件,每种方法都有... 目录 如何使用这些方法1. 使用 SqlRunner 工具类2. 使用 @Select 注解3. 使用

Linux kill正在执行的后台任务 kill进程组使用详解

《Linuxkill正在执行的后台任务kill进程组使用详解》文章介绍了两个脚本的功能和区别,以及执行这些脚本时遇到的进程管理问题,通过查看进程树、使用`kill`命令和`lsof`命令,分析了子... 目录零. 用到的命令一. 待执行的脚本二. 执行含子进程的脚本,并kill2.1 进程查看2.2 遇到的

java中ssh2执行多条命令的四种方法

《java中ssh2执行多条命令的四种方法》本文主要介绍了java中ssh2执行多条命令的四种方法,包括分号分隔、管道分隔、EOF块、脚本调用,可确保环境配置生效,提升操作效率,具有一定的参考价值,感... 目录1 使用分号隔开2 使用管道符号隔开3 使用写EOF的方式4 使用脚本的方式大家平时有没有遇到自

mybatis直接执行完整sql及踩坑解决

《mybatis直接执行完整sql及踩坑解决》MyBatis可通过select标签执行动态SQL,DQL用ListLinkedHashMap接收结果,DML用int处理,注意防御SQL注入,优先使用#... 目录myBATiFBNZQs直接执行完整sql及踩坑select语句采用count、insert、u

一个Java的main方法在JVM中的执行流程示例详解

《一个Java的main方法在JVM中的执行流程示例详解》main方法是Java程序的入口点,程序从这里开始执行,:本文主要介绍一个Java的main方法在JVM中执行流程的相关资料,文中通过代码... 目录第一阶段:加载 (Loading)第二阶段:链接 (Linking)第三阶段:初始化 (Initia

C++统计函数执行时间的最佳实践

《C++统计函数执行时间的最佳实践》在软件开发过程中,性能分析是优化程序的重要环节,了解函数的执行时间分布对于识别性能瓶颈至关重要,本文将分享一个C++函数执行时间统计工具,希望对大家有所帮助... 目录前言工具特性核心设计1. 数据结构设计2. 单例模式管理器3. RAII自动计时使用方法基本用法高级用法

Java实现远程执行Shell指令

《Java实现远程执行Shell指令》文章介绍使用JSch在SpringBoot项目中实现远程Shell操作,涵盖环境配置、依赖引入及工具类编写,详解分号和双与号执行多指令的区别... 目录软硬件环境说明编写执行Shell指令的工具类总结jsch(Java Secure Channel)是SSH2的一个纯J

python 线程池顺序执行的方法实现

《python线程池顺序执行的方法实现》在Python中,线程池默认是并发执行任务的,但若需要实现任务的顺序执行,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋... 目录方案一:强制单线程(伪顺序执行)方案二:按提交顺序获取结果方案三:任务间依赖控制方案四:队列顺序消