我的命令行工具不断抛出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);
}
答案 0 :(得分:2)
我认为,就你而言,
pthread_create(thread, NULL, test, &args);
在此调用中,thread
是一个指针而没有分配内存。因此,基本上pthread_create()
会尝试写入未初始化的内存,这会创建undefined behavior。
在返回之前,成功调用
pthread_create()
会将新线程的ID存储在thread
指向的缓冲区中; ....
相反,你可以做
pthread_t thread;
...
pthread_create(&thread, NULL, test, &args);
答案 1 :(得分:1)
您正在使用指向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);
}
答案 2 :(得分:1)
正如其他答案所指出的那样,您需要初始化指针thread
,您只需这样做:
pthread_t thread;
pthread_create(&thread, NULL, test, &args);
那么,我必须动态分配内存,因为不同 线程在许多不同的函数中产生,因此我无法使用 局部变量,因为我不会加入线程。然后,怎么样 我可以释放分配的内存而无需等待线程 完成,即没有呼叫加入?
没有。您不需要动态分配,因为您要生成多个线程。一旦创建了一个线程,就不再需要线程标识符了解它是局部变量还是malloc
ed并不重要。只有当您需要join
或更改线程的某些特征时才需要它 - 您需要ID。否则,您甚至可以重用相同的线程来创建多个线程。例如,
pthread_t thread;
for( i = 0; i<8; i++)
pthread_create(&thread, NULL, thread_func, NULL);
非常好。如果需要,线程总是可以通过调用pthread_self()
获得自己的ID。但是,当<{1}}线程退出时,无法 将局部变量mutex1
传递给线程函数,main
不再存在,因为创建的线程继续用它。因此,您需要malloc mutex1
或将其设为全局变量。
另一件事是,如果您决定让主线程退出,那么您应该调用mutex1
。否则,当 main 线程退出时(通过调用pthread_exit()
或简单地exit
),整个过程将会死亡,这意味着所有线程也将死亡。