开发者

some weird result of pthread program

It is a very simple multithread program. It will create two threads and run.

In the thread, it will copy the argv0 to origname.

At the first time, the origname is correct.

But after entering into the while loop, the origname will be corrupted by the sprintf.

It will print like:

Hello World! It's me, thread #0 ./multithrea开发者_Python百科d 3!

origname 0 ./multithread 3!

the content of origname is the parameter for the sprintf. I don't understand what is the reason. Anyone can help?

#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);
}


Your problem is a buffer overrun. I count:

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

at over 40 characters, but you are sprintf'ing it into a 30 byte buffer. After this has happened, all bets are off. The result is undefined. It could crash, it could do weird things, it could make a nanobot and send it out to buy coffee for the entire dev team.


Your problem is coming from this line:

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

argv is defined as char **argv (same as char *argv[]), thus argv[0] is a pointer. As a result, thread_data_array[t].argv0 is an alias of the data in argv.

In the end, the two threads share the same string, and everything gets messed up. Don't ask me for the exact details of what gets screwed up when, because there are a large number of things that can happen when you do this, depending on which line of code runs when.

You need to use strcpy() instead. This way, each thread has its own copy, and the two threads to not mess with one another.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜