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

相关文章

maven 编译构建可以执行的jar包

💝💝💝欢迎莅临我的博客,很高兴能够在这里和您见面!希望您在这里可以感受到一份轻松愉快的氛围,不仅可以获得有趣的内容和知识,也可以畅所欲言、分享您的想法和见解。 推荐:「stormsha的主页」👈,「stormsha的知识库」👈持续学习,不断总结,共同进步,为了踏实,做好当下事儿~ 专栏导航 Python系列: Python面试题合集,剑指大厂Git系列: Git操作技巧GO

ORACLE 11g 创建数据库时 Enterprise Manager配置失败的解决办法 无法打开OEM的解决办法

在win7 64位系统下安装oracle11g,在使用Database configuration Assistant创建数据库时,在创建到85%的时候报错,错误如下: 解决办法: 在listener.ora中增加对BlueAeri-PC或ip地址的侦听,具体步骤如下: 1.启动Net Manager,在“监听程序”--Listener下添加一个地址,主机名写计

jenkins 插件执行shell命令时,提示“Command not found”处理方法

首先提示找不到“Command not found,可能我们第一反应是查看目标机器是否已支持该命令,不过如果相信能找到这里来的朋友估计遇到的跟我一样,其实目标机器是没有问题的通过一些远程工具执行shell命令是可以执行。奇怪的就是通过jenkinsSSH插件无法执行,经一番折腾各种搜索发现是jenkins没有加载/etc/profile导致。 【解决办法】: 需要在jenkins调用shell脚

linux 下Time_wait过多问题解决

转自:http://blog.csdn.net/jaylong35/article/details/6605077 问题起因: 自己开发了一个服务器和客户端,通过短连接的方式来进行通讯,由于过于频繁的创建连接,导致系统连接数量被占用,不能及时释放。看了一下18888,当时吓到了。 现象: 1、外部机器不能正常连接SSH 2、内向外不能够正常的ping通过,域名也不能正常解析。

STM32 ADC+DMA导致写FLASH失败

最近用STM32G070系列的ADC+DMA采样时,遇到了一些小坑记录一下; 一、ADC+DMA采样时进入死循环; 解决方法:ADC-dma死循环问题_stm32 adc dma死机-CSDN博客 将ADC的DMA中断调整为最高,且增大ADCHAL_ADC_Start_DMA(&hadc1, (uint32_t*)adc_buffer, ADC_Buffer_Size); 的ADC_Bu

Lua 脚本在 Redis 中执行时的原子性以及与redis的事务的区别

在 Redis 中,Lua 脚本具有原子性是因为 Redis 保证在执行脚本时,脚本中的所有操作都会被当作一个不可分割的整体。具体来说,Redis 使用单线程的执行模型来处理命令,因此当 Lua 脚本在 Redis 中执行时,不会有其他命令打断脚本的执行过程。脚本中的所有操作都将连续执行,直到脚本执行完成后,Redis 才会继续处理其他客户端的请求。 Lua 脚本在 Redis 中原子性的原因

Smarty模板执行原理

为了实现程序的业务逻辑和内容表现页面的分离从而提高开发速度,php 引入了模板引擎的概念,php 模板引擎里面最流行的可以说是smarty了,smarty因其功能强大而且速度快而被广大php web开发者所认可。本文将记录一下smarty模板引擎的工作执行原理,算是加深一下理解。 其实所有的模板引擎的工作原理是差不多的,无非就是在php程序里面用正则匹配将模板里面的标签替换为php代码从而将两者

(function() {})();只执行一次

测试例子: var xx = (function() {     (function() { alert(9) })(); alert(10)     return "yyyy";  })(); 调用: alert(xx); 在调用的时候,你会发现只弹出"yyyy"信息,并不见弹出"10"的信息!这也就是说,这个匿名函数只在立即调用的时候执行一次,这时它已经赋予了给xx变量,也就是只是

Java程序到CPU上执行 的步骤

相信很多的小伙伴在最初学习编程的时候会容易产生一个疑惑❓,那就是编写的Java代码究竟是怎么一步一步到CPU上去执行的呢?CPU又是如何执行的呢?今天跟随小编的脚步去化解开这个疑惑❓。 在学习这个过程之前,我们需要先讲解一些与本内容相关的知识点 指令 指令是指导CPU运行的命令,主要由操作码+被操作数组成。 其中操作码用来表示要做什么动作,被操作数是本条指令要操作的数据,可能是内存地址,也

Android下执行linux命令

最近在开发过程中 使用了几个命令来对   手机的文件的权限进行修改;现在记录一下: 用到的方法: 1:判断是否有Root权限;  /**      * 判断当前手机是否有ROOT权限      * @return      */     public static boolean isRoot(){         boolean bool = false;         try{