使用pthread

时间:2015-06-23 19:38:05

标签: c multithreading debugging 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);
}

3 个答案:

答案 0 :(得分:2)

我认为,就你而言,

pthread_create(thread, NULL, test, &args);

在此调用中,thread是一个指针而没有分配内存。因此,基本上pthread_create()会尝试写入未初始化的内存,这会创建undefined behavior

参考pthread_create()

的手册页
  

在返回之前,成功调用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),整个过程将会死亡,这意味着所有线程也将死亡。