使用 pthreads 获取总线错误 10
Getting bus error 10 with pthreads
我的命令行工具不断抛出 bus error: 10
消息。 Xcode 调试器显示 EXC_BAD_ACCESS
消息并突出显示创建线程的函数调用。手动调试显示执行流在线程流内的随机位置中断。我尝试了另一个编译器(gcc),但结果是一样的。禁用 pthread_mutex_lock()
和 pthread_mutex_unlock()
没有帮助。我写了这个重现错误的小例子。
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
typedef struct thread_args {
pthread_mutex_t* mutex;
} thread_args;
void* test(void* t_args) {
printf("Thread initiated\n");
thread_args* args = (thread_args* )t_args;
printf("Args casted\n");
pthread_mutex_lock(args->mutex);
printf("Mutex locked\n");
pthread_mutex_unlock(args->mutex);
printf("Mutex unlocked\n");
pthread_exit(NULL);
}
int main() {
pthread_mutex_t mutex1;
pthread_mutex_init(&mutex1, NULL);
thread_args args;
args.mutex = &mutex1;
pthread_t* thread;
printf("Initiating a thread\n");
pthread_create(thread, NULL, test, &args);
return(0);
}
我认为,在你的情况下,
pthread_create(thread, NULL, test, &args);
在这个调用中,thread
是一个指针,没有分配内存。因此,本质上 pthread_create()
尝试写入未初始化的内存,这会创建 undefined behavior.
的手册页
Before returning, a successful call to pthread_create()
stores the ID of the new thread in the buffer pointed to by thread
;....
相反,您可以这样做
pthread_t thread;
...
pthread_create(&thread, NULL, test, &args);
您正在使用指向 pthread_t
的未初始化指针。 pthread_t
的实际存储需要在某个地方!
尝试:
int main() {
pthread_mutex_t mutex1;
pthread_mutex_init(&mutex1, NULL);
thread_args args;
args.mutex = &mutex1;
pthread_t thread;
printf("Initiating a thread\n");
pthread_create(&thread, NULL, test, &args);
return(0);
}
正如其他答案所指出的,您需要初始化您的指针 thread
,您可以简单地这样做:
pthread_t thread;
pthread_create(&thread, NULL, test, &args);
Well, then I'll have to allocate memory dynamically, because different
threads are spawned inside many different functions, hence I can't use
local variables, because I'm not going to join the threads. Then, how
can I free the allocated memory without waiting for the thread to
finish, i.e. without calling join?
没有。您不需要仅仅因为要生成多个线程而动态分配。一旦线程被创建,线程标识符就不再需要了,所以它是局部变量还是 malloc
ed 并不重要。仅当您需要 join
或更改线程的某些特征时才需要它——为此您需要 ID。否则,您甚至可以重用同一个线程来创建多个线程。例如,
pthread_t thread;
for( i = 0; i<8; i++)
pthread_create(&thread, NULL, thread_func, NULL);
完全没问题。如果需要,线程始终可以通过调用 pthread_self()
来获取自己的 ID。但是你 不能 将局部变量 mutex1
传递给线程函数,因为一旦 main
线程退出, mutex1
不再退出,因为线程创建继续使用它。因此,您要么需要 malloc mutex1
,要么将其设为全局变量。
另一件事是,如果您决定让主线程退出,那么您应该调用pthread_exit()
。否则,当 main 线程退出时(通过调用 exit
或简单地 return
),那么整个进程都会死掉,也就是说,所有线程也会死掉。
我的命令行工具不断抛出 bus error: 10
消息。 Xcode 调试器显示 EXC_BAD_ACCESS
消息并突出显示创建线程的函数调用。手动调试显示执行流在线程流内的随机位置中断。我尝试了另一个编译器(gcc),但结果是一样的。禁用 pthread_mutex_lock()
和 pthread_mutex_unlock()
没有帮助。我写了这个重现错误的小例子。
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
typedef struct thread_args {
pthread_mutex_t* mutex;
} thread_args;
void* test(void* t_args) {
printf("Thread initiated\n");
thread_args* args = (thread_args* )t_args;
printf("Args casted\n");
pthread_mutex_lock(args->mutex);
printf("Mutex locked\n");
pthread_mutex_unlock(args->mutex);
printf("Mutex unlocked\n");
pthread_exit(NULL);
}
int main() {
pthread_mutex_t mutex1;
pthread_mutex_init(&mutex1, NULL);
thread_args args;
args.mutex = &mutex1;
pthread_t* thread;
printf("Initiating a thread\n");
pthread_create(thread, NULL, test, &args);
return(0);
}
我认为,在你的情况下,
pthread_create(thread, NULL, test, &args);
在这个调用中,thread
是一个指针,没有分配内存。因此,本质上 pthread_create()
尝试写入未初始化的内存,这会创建 undefined behavior.
Before returning, a successful call to
pthread_create()
stores the ID of the new thread in the buffer pointed to bythread
;....
相反,您可以这样做
pthread_t thread;
...
pthread_create(&thread, NULL, test, &args);
您正在使用指向 pthread_t
的未初始化指针。 pthread_t
的实际存储需要在某个地方!
尝试:
int main() {
pthread_mutex_t mutex1;
pthread_mutex_init(&mutex1, NULL);
thread_args args;
args.mutex = &mutex1;
pthread_t thread;
printf("Initiating a thread\n");
pthread_create(&thread, NULL, test, &args);
return(0);
}
正如其他答案所指出的,您需要初始化您的指针 thread
,您可以简单地这样做:
pthread_t thread;
pthread_create(&thread, NULL, test, &args);
Well, then I'll have to allocate memory dynamically, because different threads are spawned inside many different functions, hence I can't use local variables, because I'm not going to join the threads. Then, how can I free the allocated memory without waiting for the thread to finish, i.e. without calling join?
没有。您不需要仅仅因为要生成多个线程而动态分配。一旦线程被创建,线程标识符就不再需要了,所以它是局部变量还是 malloc
ed 并不重要。仅当您需要 join
或更改线程的某些特征时才需要它——为此您需要 ID。否则,您甚至可以重用同一个线程来创建多个线程。例如,
pthread_t thread;
for( i = 0; i<8; i++)
pthread_create(&thread, NULL, thread_func, NULL);
完全没问题。如果需要,线程始终可以通过调用 pthread_self()
来获取自己的 ID。但是你 不能 将局部变量 mutex1
传递给线程函数,因为一旦 main
线程退出, mutex1
不再退出,因为线程创建继续使用它。因此,您要么需要 malloc mutex1
,要么将其设为全局变量。
另一件事是,如果您决定让主线程退出,那么您应该调用pthread_exit()
。否则,当 main 线程退出时(通过调用 exit
或简单地 return
),那么整个进程都会死掉,也就是说,所有线程也会死掉。