sem_post 处的段错误
Segfault at sem_post
我正在尝试使用信号量编写一个小型 C 程序,但我遇到了无法解决的问题。我总是在 sem_post 处遇到段错误。
这是我的服务器代码中主要方法的相关部分:
sem_t * sem_query = NULL;
sem_t * sem_server = NULL;
sem_t * sem_client = NULL;
//prepare semaphores
init_semaphores(sem_query, sem_server, sem_client);
//prepare the shared memory
struct shm_struct * shared = init_shm();
int exit_code = 0;
while (1) {
if (sem_post(sem_query) == -1) {
perror("Error posting the semaphore!");
exit_code = 1;
break;
}
if (sem_wait(sem_server) == -1) {
if (errno == EINTR) {
printf("Received interrupting signal! Quitting now...");
break;
} else {
perror("Error while waiting on semaphore!");
exit_code = 1;
break;
}
}
//calculate the response and write it to shm
calculate_and_write_response(shared, procs);
if (sem_post(sem_client) == -1) {
perror("Error posting the semaphore!");
exit_code = 1;
break;
}
if (sem_wait(sem_server) == -1) {
if (errno == EINTR) {
printf("Received interrupting signal! Quitting now...");
break;
} else {
perror("Error while waiting on semaphore!");
exit_code = 1;
break;
}
}
}
free_shm(shared);
free_semaphores(sem_query, sem_server, sem_client);
exit(exit_code);
这里是 init_semaphores 方法:
static void init_semaphores(sem_t * s1, sem_t * s2, sem_t * s3) {
s1 = sem_open(SEM_A_NAME, O_CREAT | O_EXCL, 0600, 0);
s2 = sem_open(SEM_B_NAME, O_CREAT | O_EXCL, 0600, 0);
s3 = sem_open(SEM_C_NAME, O_CREAT | O_EXCL, 0600, 0);
if (s1 == SEM_FAILED || s2 == SEM_FAILED || s3 == SEM_FAILED) {
perror("Could not open semaphores!");
free_semaphores(s1, s2, s3);
exit(1);
}
}
我没有在这里发布客户端线程的代码,因为它是无关紧要的:段错误在我启动服务器后立即发生,没有客户端进程 运行。 None 我的错误消息是在段错误之前打印的。
这是 gdb 在 运行 程序时说的内容:
Program received signal SIGSEGV, Segmentation fault.
0x00007ffff79c6b44 in sem_post@@GLIBC_2.2.5 () from /lib64/libpthread.so.0
Missing separate debuginfos, use: debuginfo-install glibc-2.17-157.el7_3.1.x86_64
所以,如果我没看错的话,段错误发生在 sem_post() 调用中,这必须是 sem_query 上的第一个调用,因为程序会在 sem_query 上等待=30=]() 调用。
代码有什么问题?段错误从何而来?
你的信号量初始化不正确:
init_semaphores(sem_query, sem_server, sem_client);
函数init_semaphores
只会修改本地副本(s1
、s2
和s3
)。因此 init_semaphores()
中的更改不会更改 main() 中的指针,从而使您的信号量设置为 NULL。而是将指针传递给指针以修改它们:
//prepare semaphores
init_semaphores(&sem_query, &sem_server, &sem_client);
和
static void init_semaphores(sem_t **s1, sem_t **s2, sem_t **s3) {
*s1 = sem_open(SEM_A_NAME, O_CREAT | O_EXCL, 0600, 0);
*s2 = sem_open(SEM_B_NAME, O_CREAT | O_EXCL, 0600, 0);
*s3 = sem_open(SEM_C_NAME, O_CREAT | O_EXCL, 0600, 0);
if (*s1 == SEM_FAILED || *s2 == SEM_FAILED || *s3 == SEM_FAILED) {
perror("Could not open semaphores!");
free_semaphores(*s1, *s2, *s3);
exit(1);
}
}
我正在尝试使用信号量编写一个小型 C 程序,但我遇到了无法解决的问题。我总是在 sem_post 处遇到段错误。 这是我的服务器代码中主要方法的相关部分:
sem_t * sem_query = NULL;
sem_t * sem_server = NULL;
sem_t * sem_client = NULL;
//prepare semaphores
init_semaphores(sem_query, sem_server, sem_client);
//prepare the shared memory
struct shm_struct * shared = init_shm();
int exit_code = 0;
while (1) {
if (sem_post(sem_query) == -1) {
perror("Error posting the semaphore!");
exit_code = 1;
break;
}
if (sem_wait(sem_server) == -1) {
if (errno == EINTR) {
printf("Received interrupting signal! Quitting now...");
break;
} else {
perror("Error while waiting on semaphore!");
exit_code = 1;
break;
}
}
//calculate the response and write it to shm
calculate_and_write_response(shared, procs);
if (sem_post(sem_client) == -1) {
perror("Error posting the semaphore!");
exit_code = 1;
break;
}
if (sem_wait(sem_server) == -1) {
if (errno == EINTR) {
printf("Received interrupting signal! Quitting now...");
break;
} else {
perror("Error while waiting on semaphore!");
exit_code = 1;
break;
}
}
}
free_shm(shared);
free_semaphores(sem_query, sem_server, sem_client);
exit(exit_code);
这里是 init_semaphores 方法:
static void init_semaphores(sem_t * s1, sem_t * s2, sem_t * s3) {
s1 = sem_open(SEM_A_NAME, O_CREAT | O_EXCL, 0600, 0);
s2 = sem_open(SEM_B_NAME, O_CREAT | O_EXCL, 0600, 0);
s3 = sem_open(SEM_C_NAME, O_CREAT | O_EXCL, 0600, 0);
if (s1 == SEM_FAILED || s2 == SEM_FAILED || s3 == SEM_FAILED) {
perror("Could not open semaphores!");
free_semaphores(s1, s2, s3);
exit(1);
}
}
我没有在这里发布客户端线程的代码,因为它是无关紧要的:段错误在我启动服务器后立即发生,没有客户端进程 运行。 None 我的错误消息是在段错误之前打印的。
这是 gdb 在 运行 程序时说的内容:
Program received signal SIGSEGV, Segmentation fault.
0x00007ffff79c6b44 in sem_post@@GLIBC_2.2.5 () from /lib64/libpthread.so.0
Missing separate debuginfos, use: debuginfo-install glibc-2.17-157.el7_3.1.x86_64
所以,如果我没看错的话,段错误发生在 sem_post() 调用中,这必须是 sem_query 上的第一个调用,因为程序会在 sem_query 上等待=30=]() 调用。
代码有什么问题?段错误从何而来?
你的信号量初始化不正确:
init_semaphores(sem_query, sem_server, sem_client);
函数init_semaphores
只会修改本地副本(s1
、s2
和s3
)。因此 init_semaphores()
中的更改不会更改 main() 中的指针,从而使您的信号量设置为 NULL。而是将指针传递给指针以修改它们:
//prepare semaphores
init_semaphores(&sem_query, &sem_server, &sem_client);
和
static void init_semaphores(sem_t **s1, sem_t **s2, sem_t **s3) {
*s1 = sem_open(SEM_A_NAME, O_CREAT | O_EXCL, 0600, 0);
*s2 = sem_open(SEM_B_NAME, O_CREAT | O_EXCL, 0600, 0);
*s3 = sem_open(SEM_C_NAME, O_CREAT | O_EXCL, 0600, 0);
if (*s1 == SEM_FAILED || *s2 == SEM_FAILED || *s3 == SEM_FAILED) {
perror("Could not open semaphores!");
free_semaphores(*s1, *s2, *s3);
exit(1);
}
}