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.
精彩评论