- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
我是信号量的新手,想在我的程序中添加多线程,但我无法解决以下问题:只要我没有设置 SA_RESTART,sem_wait() 应该能够接收 EINTR 并解锁旗帜。我正在向在 sem_wait() 中阻塞的工作线程发送一个 SIGUSR1,它确实接收到信号并被中断,但它会继续阻塞,所以它永远不会给我一个 -1 返回码和 errno = EINTR .但是,如果我从主线程执行 sem_post,它将解除阻塞,给我一个 EINTR 的错误号,但 RC 为 0。我对这种行为感到非常困惑。它是一些奇怪的 NetBSD 实现还是我在这里做错了什么?根据手册页,sem_wait 符合 POSIX.1 (ISO/IEC 9945-1:1996)。一个简单的代码:
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <signal.h>
#include <pthread.h>
#include <semaphore.h>
typedef struct workQueue_s
{
int full;
int empty;
sem_t work;
int sock_c[10];
} workQueue_t;
void signal_handler( int sig )
{
switch( sig )
{
case SIGUSR1:
printf( "Signal: I am pthread %p\n", pthread_self() );
break;
}
}
extern int errno;
workQueue_t queue;
pthread_t workerbees[8];
void *BeeWork( void *t )
{
int RC;
pthread_t tid;
struct sigaction sa;
sa.sa_handler = signal_handler;
sigaction( SIGUSR1, &sa, NULL );
printf( "Bee: I am pthread %p\n", pthread_self() );
RC = sem_wait( &queue.work );
printf( "Bee: got RC = %d and errno = %d\n", RC, errno );
RC = sem_wait( &queue.work );
printf( "Bee: got RC = %d and errno = %d\n", RC, errno );
pthread_exit( ( void * ) t );
}
int main()
{
int RC;
long tid = 0;
pthread_attr_t attr;
pthread_attr_init( &attr );
pthread_attr_setdetachstate( &attr, PTHREAD_CREATE_JOINABLE );
queue.full = 0;
queue.empty = 0;
sem_init( &queue.work, 0, 0 );
printf( "I am pthread %p\n", pthread_self() );
pthread_create( &workerbees[tid], &attr, BeeWork, ( void * ) tid );
pthread_attr_destroy( &attr );
sleep( 2 );
sem_post( &queue.work );
sleep( 2 );
pthread_kill( workerbees[tid], SIGUSR1 );
sleep( 2 );
// Remove this and sem_wait will stay blocked
sem_post( &queue.work );
sleep( 2 );
return( 0 );
}
我知道 printf 在信号处理程序中并不大声,但只是为了它,如果我删除它,我会得到相同的结果。
这些是没有 sem_post 的结果:
I am pthread 0x7f7fffc00000
Bee: I am pthread 0x7f7ff6c00000
Bee: got RC = 0 and errno = 0
Signal: I am pthread 0x7f7ff6c00000
还有 sem_post:
I am pthread 0x7f7fffc00000
Bee: I am pthread 0x7f7ff6c00000
Bee: got RC = 0 and errno = 0
Signal: I am pthread 0x7f7ff6c00000
Bee: got RC = 0 and errno = 4
我知道我并不真的需要解锁并且可以简单地从 main 中退出,但我还是希望看到它正常工作。我使用 sem_wait 的原因是因为我想让工作线程保持事件状态,并在有来自 Postfix 的新客户端连接时立即使用 sem_post 从主线程唤醒等待时间最长的线程。我不想一直执行 pthread_create,因为我每秒会收到多次调用,我不想失去速度并使 Postfix 对新的 smtpd 客户端无响应。它是 Postfix 的策略守护进程,服务器非常繁忙。
我是不是漏掉了什么? NetBSD 只是搞砸了吗?
最佳答案
我的帖子是关于 Linux 上的行为,但我认为您可能有类似的行为,或者至少我认为可能会有帮助。如果没有,请告诉我,我会删除这个无用的“噪音”。
我试图重现您的设置,看到您所描述的情况我感到非常惊讶。更深入地观察帮助我弄清楚实际上还有更微妙的东西;如果你看看 strace,你会看到类似的东西:
[pid 6984] futex(0x6020e8, FUTEX_WAIT_PRIVATE, 0, NULL <unfinished ...>
[pid 6983] rt_sigprocmask(SIG_BLOCK, [CHLD], [], 8) = 0
[pid 6983] rt_sigaction(SIGCHLD, NULL, {SIG_DFL, [], 0}, 8) = 0
[pid 6983] rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0
[pid 6983] nanosleep({2, 0}, 0x7fffe5794a70) = 0
[pid 6983] tgkill(6983, 6984, SIGUSR1 <unfinished ...>
[pid 6984] <... futex resumed> ) = ? ERESTARTSYS (To be restarted if SA_RESTART is set)
[pid 6983] <... tgkill resumed> ) = 0
[pid 6984] --- SIGUSR1 {si_signo=SIGUSR1, si_code=SI_TKILL, si_pid=6983, si_uid=500} ---
[pid 6983] rt_sigprocmask(SIG_BLOCK, [CHLD], <unfinished ...>
[pid 6984] rt_sigreturn( <unfinished ...>
[pid 6983] <... rt_sigprocmask resumed> [], 8) = 0
[pid 6984] <... rt_sigreturn resumed> ) = -1 EINTR (Interrupted system call)
查看带有ERESTARTSYS
和EINTR
的行:被中断的系统调用实际上是rt_sigreturn resumed
,而不是futex
(sem_wait 下的系统调用)如您所料。我必须说我很困惑,但阅读这个人给出了一些有趣的线索(man 7 信号):
If a blocked call to one of the following interfaces is interrupted by
a signal handler, then the call will be automatically restarted after
the signal handler returns if the SA_RESTART flag was used; otherwise
the call will fail with the error EINTR:
[...]
* futex(2) FUTEX_WAIT (since Linux 2.6.22; beforehand, always
failed with EINTR).
所以我猜你有一个具有类似行为的内核(请参阅 netBSD 文档?)并且你可以观察到系统调用自动重启而你没有任何机会看到它。
就是说,我从你的程序中完全删除了 sem_post() 并且只是发送信号“中断” sem_wait() 并查看我看到的 strace(在蜜蜂线程上过滤):
[pid 8309] futex(0x7fffc0470990, FUTEX_WAIT_PRIVATE, 0, NULL <unfinished ...>
[pid 8309] <... futex resumed> ) = ? ERESTARTSYS (To be restarted if SA_RESTART is set)
[pid 8309] --- SIGUSR1 {si_signo=SIGUSR1, si_code=SI_TKILL, si_pid=8308, si_uid=500} ---
[pid 8309] rt_sigreturn() = -1 EINTR (Interrupted system call)
[pid 8309] madvise(0x7fd5f6019000, 8368128, MADV_DONTNEED) = 0
[pid 8309] _exit(0)
我必须说我不掌握细节,但内核似乎找出了我试图站在哪里并使整个事情具有正确的行为:
Bee: got RC = -1 and errno = Interrupted system call
关于c - sem_wait 未使用 EINTR 解锁,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33853901/
我找到了 this excellent question and answer它以 x/y(加上 center x/y 和 degrees/radians)开始并计算旋转- 到 x'/y'。这个计算很
全部: 我已经创建了一个 Windows 窗体和一个按钮。在另一个线程中,我试图更改按钮的文本,但它崩溃了;但是如果我尝试更改按钮的颜色,它肯定会成功。我认为如果您更改任何 Windows 窗体控件属
本网站的另一个问题已证实,C 中没有缩写的字面后缀,并且可以执行以下操作: short Number = (short)1; 但是转换它和不这样做有什么区别: short Number = 1; 您使
我有下表: ID (int) EMAIL (varchar(50)) CAMPAIGNID (int) isSubscribe (bit) isActionByUser (bit) 此表存储了用户对事
也就是说,无需触发Javascript事件即可改变的属性,如何保留我手动选中或取消选中的复选框的状态,然后复制到另一个地方? 运行下面的代码片段并选中或取消选中其中的一些,然后点击“复制”: $('#
我在网上找到的所有关于递增指针导致段错误的示例都涉及指针的取消引用 - 如果我只想递增它(例如在 for 循环的末尾)并且我不在乎它是否最终进入无效内存,因为我不会再使用它。例如,在这个程序中,每次迭
我有一个 Spring MVC REST 服务,它使用 XStream 将消息与 XML 相互转换。 有什么方法可以将请求和响应中的 xml(即正文)打印到普通的 log4j 记录器? 在 Contr
做我的任务有一个很大的挑战,那就是做相互依赖的任务我在这张照片中说的。假设我们有两个任务 A 和 B,执行子任务 A1、A2 和 B1、B2,假设任务 B 依赖于 A。 要理想地执行任务 B,您应该执
通过阅读该网站上的几个答案,我了解到 CoInitialize(Ex) should be called by the creator of a thread 。然后,在该线程中运行的任何代码都可以使
这个问题已经困扰我一段时间了。我以前从未真正使用过 ListViews,也没有使用过 FirebaseListAdapters。我想做的就是通过显示 id 和用户位置来启动列表的基础,但由于某种原因,
我很难解释这两个(看似简单)句子的含义: “受检异常由编译器在编译时检查” 这是什么意思?编译器检查是否捕获了所有已检查的异常(在代码中抛出)? “未经检查的异常在运行时检查,而不是编译时” 这句话中
我有一个包含排除子字符串的文本文件,我想迭代该文件以检查并返回不带排除子字符串的输入项。 这里我使用 python 2.4,因此下面的代码可以实现此目的,因为 with open 和 any 不起作用
Spring 的缓存框架能否了解请求上下文的身份验证状态,或者更容易推出自己的缓存解决方案? 最佳答案 尽管我发现这个用例 super 奇怪,但您可以为几乎任何与 SpEL 配合使用的内容设置缓存条件
我有以下函数模板: template HeldAs* duplicate(MostDerived *original, HeldAs *held) { // error checking omi
如果我的应用程序具有设备管理员/设备所有者权限(未获得 root 权限),我如何才能从我的应用程序中终止(或阻止启动)另一个应用程序? 最佳答案 设备所有者可以阻止应用程序: DevicePolicy
非常简单的问题,但我似乎无法让它正常工作。 我有一个组件,其中有一些 XSLT(用于导航)。它通过 XSLT TBB 使用 XSLT Mediator 发布。 发布后
我正在将一个对象拖动到一个可拖放的对象内,该对象也是可拖动的。放置对象后,它会嵌套在可放置对象内。同样,如果我将对象拖到可放置的外部,它就不再嵌套。 但是,如果我经常拖入和拖出可放置对象,则可拖动对象
我正在尝试为按钮和弹出窗口等多个指令实现“取消选择”功能。也就是说,我希望当用户单击不属于指令模板一部分的元素时触发我的函数。目前,我正在使用以下 JQuery 代码: $('body').click
我从 this question 得到了下面的代码,该脚本用于在 Google tasks 上更改 iframe[src="about:blank"] 内的 CSS使用 Chrome 扩展 Tempe
我有一些 @Mock 对象,但没有指定在该对象上调用方法的返回值。该方法返回 int (不是 Integer)。我很惊讶地发现 Mockito 没有抛出 NPE 并返回 0。这是预期的行为吗? 例如:
我是一名优秀的程序员,十分优秀!