C-尝试将字符传递给pthread_create,发生分段错误

时间:2014-10-17 20:08:41

标签: c multithreading segmentation-fault pthreads

好吧,所以我已经获得了4个pthread创作(我创建了4个主题,每个主题将管理一个主要方向,北,南,东或西):

if ((rc = pthread_create(&tidn, NULL, threadcode, (void *)'n')) != 0)
    fprintf(stderr, "thread create failed (%s)\n", strerror(rc)), exit(1);
if ((rc = pthread_create(&tids, NULL, threadcode, (void *)'s')) != 0)
    fprintf(stderr, "thread create failed (%s)\n", strerror(rc)), exit(1);
if ((rc = pthread_create(&tide, NULL, threadcode, (void *)'e')) != 0)
    fprintf(stderr, "thread create failed (%s)\n", strerror(rc)), exit(1);
if ((rc = pthread_create(&tidw, NULL, threadcode, (void *)'w')) != 0)
    fprintf(stderr, "thread create failed (%s)\n", strerror(rc)), exit(1);

我已经获得了我的线程代码功能

void *threadcode(void* dir)
{
char* direction;
struct cart_t *cart = NULL;

direction = (char*)dir;

printf("casted direction %c\n", *direction);

fprintf(stderr, "thread for direction %c starts\n", *direction);
cart = q_getCart(*direction);
while (cart != NULL) {
    fprintf(stderr, "thread for direction %c gets cart %i\n",
        *direction, cart->num);
    monitor_arrive(cart);
    monitor_cross(cart);
    monitor_leave(cart);
    cart = q_getCart(*direction);
}
fprintf(stderr, "thread for direction %c exits\n", *direction);

return NULL;
}

由于某种原因,创建了线程,但在创建过程中,代码段出错。我不确定它在哪里发生,但我很确定它在线程代码函数中的某个地方,因为线程将开始创建但会失败。

1 个答案:

答案 0 :(得分:2)

您对传递给pthread_create()的内容犯了严重错误:

  1. 预计void *。您正尝试将其传递给int。这是实现定义的行为,可能在某些情况下可以合理地工作,但最好避免它。传递给它一个实际的指针。

  2. 如果您传递int,那么您至少应该将其转换回线程函数中的int。你实际上试图转换成char *,它甚至不接近你传递的内容。然后你尝试取消引用那个虚假的指针来获取一个角色,这就是为什么你要分裂。

  3. 这是你应该做的一个例子。请注意,在没有某种同步的情况下,您不应该在多个线程中调用printf()fprintf()等函数(或perror(),但是对于一个简单的示例,它将立即退出无论如何,我会抓住机会)。您没有显示实现,但是您可能会同样保护您正在调用的其他一些函数。

    #define _POSIX_C_SOURCE 200809L
    
    #include <stdio.h>
    #include <stdlib.h>
    #include <pthread.h>
    
    pthread_mutex_t io_mtx = PTHREAD_MUTEX_INITIALIZER;
    
    void * threadcode(void * arg)
    {
        const char c = *((char *) arg);
    
        if ( pthread_mutex_lock(&io_mtx) != 0 ) {
            perror("couldn't acquire mutex");
            exit(EXIT_FAILURE);
        }
    
        printf("Entered thread for '%c'\n", c);
    
        if ( pthread_mutex_unlock(&io_mtx) != 0 ) {
            perror("couldn't release mutex");
            exit(EXIT_FAILURE);
        }
    
        return NULL;
    }
    
    int main(void)
    {
        pthread_t tidn, tids, tide, tidw;
        static char * dirs = "nsew";
    
        /*  Create threads  */
    
        if ( pthread_create(&tidn, NULL, threadcode, &dirs[0]) != 0 ) {
            perror("couldn't create north thread");
            return EXIT_FAILURE;
        }
        if ( pthread_create(&tids, NULL, threadcode, &dirs[1]) != 0 ) {
            perror("couldn't create south thread");
            return EXIT_FAILURE;
        }
        if ( pthread_create(&tide, NULL, threadcode, &dirs[2]) != 0 ) {
            perror("couldn't create east thread");
            return EXIT_FAILURE;
        }
        if ( pthread_create(&tidw, NULL, threadcode, &dirs[3]) != 0 ) {
            perror("couldn't create west thread");
            return EXIT_FAILURE;
        }
    
        /*  State that threads are created  */
    
        if ( pthread_mutex_lock(&io_mtx) != 0 ) {
            perror("couldn't acquire mutex");
            exit(EXIT_FAILURE);
        }
    
        printf("Threads created\n");
    
        if ( pthread_mutex_unlock(&io_mtx) != 0 ) {
            perror("couldn't release mutex");
            exit(EXIT_FAILURE);
        }
    
        /*  Join threads  */
    
        if ( pthread_join(tidn, NULL) != 0 ) {
            perror("couldn't join with north thread");
            return EXIT_FAILURE;
        }
        if ( pthread_join(tids, NULL) != 0 ) {
            perror("couldn't join with south thread");
            return EXIT_FAILURE;
        }
        if ( pthread_join(tide, NULL) != 0 ) {
            perror("couldn't join with east thread");
            return EXIT_FAILURE;
        }
        if ( pthread_join(tidw, NULL) != 0 ) {
            perror("couldn't join with west thread");
            return EXIT_FAILURE;
        }
    
        return 0;
    }
    

    可能的输出:

    paul@horus:~/Documents/src/sandbox$ ./thread
    Entered thread for 'n'
    Entered thread for 's'
    Entered thread for 'w'
    Threads created
    Entered thread for 'e'
    paul@horus:~/Documents/src/sandbox$