pthread程序有些奇怪的结果

时间:2010-11-11 16:22:43

标签: c pthreads

这是一个非常简单的多线程程序。它将创建两个线程并运行。

在帖子中,它会将argv0复制到origname

第一次origname是正确的。

但进入while循环后,sprintf会破坏origname。

它将打印如下:

Hello World! It's me, thread #0 ./multithread 3!

origname 0 ./multithread 3!

origname的内容是sprintf的参数。我不明白是什么原因。有人可以帮忙吗?

#include <pthread.h>
#include <stdio.h>
#define NUM_THREADS     2
void sendstring(char *string)
{
    printf("%s",string);
}
struct thread_data{
    int  thread_id;
    char *argv0;
};

struct thread_data thread_data_array[NUM_THREADS];


void *PrintHello(void *parameter)
{
    struct thread_data *childpara;
    childpara = (struct thread_data *)parameter;
    int i = 0;
    char origname[20];
    strncpy(origname, childpara->argv0,strlen(childpara->argv0));
    origname[strlen(childpara->argv0)] = '\0';
    printf("init origname %s argv0 %s\n",origname, childpara->argv0);

    while(1)
    {
            printf("origname %s\n",origname);
            sleep(1);
            char buffer[30];
            sprintf(buffer,"Hello World! It's me, thread #%ld %s %d!\n", childpara->thread_id, childpara->argv0, i++);
            sendstring(buffer);
    }
    pthread_exit(NULL);
}

int main (int argc, char *argv[])
{
    pthread_t threads[NUM_THREADS];
    int rc;
    long t;
    for(t=0; t<NUM_THREADS; t++){
            thread_data_array[t].thread_id = t;
            thread_data_array[t].argv0 = argv[0];
            rc = pthread_create(&threads[t], NULL, PrintHello,(void *) &thread_data_array[t]);      

            if (rc){
                    printf("ERROR; return code from pthread_create() is %d\n", rc);
                    exit(-1);
            }
    }
    pthread_exit(NULL);
}

2 个答案:

答案 0 :(得分:2)

您的问题是缓冲区溢出。我算了:

Hello World! It's me, thread #0 ./multithread 3!

超过40个字符,但是你正在将它打入30字节的缓冲区。在这发生之后,所有的赌注都没有了。结果未定义。它可能会崩溃,它可以做一些奇怪的事情,它可以制作一个纳米机器人并将其发送给整个开发团队购买咖啡。

答案 1 :(得分:0)

你的问题来自这条线:

thread_data_array[t].argv0 = argv[0];

argv定义为char **argv(与char *argv[]相同),因此argv [0]是一个指针。因此,thread_data_array[t].argv0argv中数据的别名。

最后,两个线程共享相同的字符串,一切都搞砸了。不要问我有什么搞砸的确切细节,因为当你这样做时会发生很多事情,具体取决于代码行运行的时间。

您需要使用strcpy()代替。这样,每个线程都有自己的副本,并且两个线程不会相互混淆。