pthread_mutex_lock 和 EAGAIN
pthread_mutex_lock and EAGAIN
我已经将 pthread 用于多线程程序,但遇到了以下情况。
当我 运行 没有睡眠命令的代码时,它会在 运行 时间导致错误,当我按预期添加睡眠命令程序 运行s 时。
有睡眠:
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <pthread.h>
#include <unistd.h>
pthread_mutex_t m_writer = PTHREAD_MUTEX_INITIALIZER;
void *print_str(void *args) {
sleep(12);
char *str = (char*) args;
pthread_mutex_lock(&m_writer);
printf("%s", str);
pthread_mutex_unlock(&m_writer);
pthread_exit(NULL);
}
int main(int argc, char **argv) {
pthread_t t1;
pthread_create(&t1, NULL, print_str, "Hello\n");
pthread_mutex_lock(&m_writer);
printf("LOL\n");
pthread_mutex_unlock(&m_writer);
pthread_join(t1, NULL);
return 0;
}
没有睡眠:
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <pthread.h>
#include <unistd.h>
pthread_mutex_t m_writer = PTHREAD_MUTEX_INITIALIZER;
void *print_str(void *args) {
char *str = (char*) args;
pthread_mutex_lock(&m_writer);
printf("%s", str);
pthread_mutex_unlock(&m_writer);
pthread_exit(NULL);
}
int main(int argc, char **argv) {
pthread_t t1;
pthread_create(&t1, NULL, print_str, "Hello\n");
pthread_mutex_lock(&m_writer);
printf("LOL\n");
pthread_mutex_unlock(&m_writer);
pthread_join(t1, NULL);
return 0;
}
错误:
futex(0x559c3d3df0a0, FUTEX_WAIT_PRIVATE, 2, NULLHello
) = -1 EAGAIN (Resource temporarily unavailable)
strace
显示系统调用的结果。 Linux 中的 Pthread 函数不是系统调用,它们是在(可能不平凡的)系统调用之上实现的 libc 函数。您对内部系统调用 return 不感兴趣。对 ptread_mutex_lock
的一次成功调用可能而且有时确实需要多次失败的系统调用。
特别是,pthread_mutex_lock
不可能在这个程序中导致 EAGAIN
,因为没有尝试递归地锁定互斥锁,并且默认互斥锁在 Linux 中不是递归的. pthread_mutex_lock
在内部使用的 FUTEX_WAIT_PRIVATE
系统调用可以并且将会导致 EAGAIN
。应用程序员对此毫无兴趣。
我已经将 pthread 用于多线程程序,但遇到了以下情况。 当我 运行 没有睡眠命令的代码时,它会在 运行 时间导致错误,当我按预期添加睡眠命令程序 运行s 时。
有睡眠:
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <pthread.h>
#include <unistd.h>
pthread_mutex_t m_writer = PTHREAD_MUTEX_INITIALIZER;
void *print_str(void *args) {
sleep(12);
char *str = (char*) args;
pthread_mutex_lock(&m_writer);
printf("%s", str);
pthread_mutex_unlock(&m_writer);
pthread_exit(NULL);
}
int main(int argc, char **argv) {
pthread_t t1;
pthread_create(&t1, NULL, print_str, "Hello\n");
pthread_mutex_lock(&m_writer);
printf("LOL\n");
pthread_mutex_unlock(&m_writer);
pthread_join(t1, NULL);
return 0;
}
没有睡眠:
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <pthread.h>
#include <unistd.h>
pthread_mutex_t m_writer = PTHREAD_MUTEX_INITIALIZER;
void *print_str(void *args) {
char *str = (char*) args;
pthread_mutex_lock(&m_writer);
printf("%s", str);
pthread_mutex_unlock(&m_writer);
pthread_exit(NULL);
}
int main(int argc, char **argv) {
pthread_t t1;
pthread_create(&t1, NULL, print_str, "Hello\n");
pthread_mutex_lock(&m_writer);
printf("LOL\n");
pthread_mutex_unlock(&m_writer);
pthread_join(t1, NULL);
return 0;
}
错误:
futex(0x559c3d3df0a0, FUTEX_WAIT_PRIVATE, 2, NULLHello ) = -1 EAGAIN (Resource temporarily unavailable)
strace
显示系统调用的结果。 Linux 中的 Pthread 函数不是系统调用,它们是在(可能不平凡的)系统调用之上实现的 libc 函数。您对内部系统调用 return 不感兴趣。对 ptread_mutex_lock
的一次成功调用可能而且有时确实需要多次失败的系统调用。
特别是,pthread_mutex_lock
不可能在这个程序中导致 EAGAIN
,因为没有尝试递归地锁定互斥锁,并且默认互斥锁在 Linux 中不是递归的. pthread_mutex_lock
在内部使用的 FUTEX_WAIT_PRIVATE
系统调用可以并且将会导致 EAGAIN
。应用程序员对此毫无兴趣。