C程序在创建几个线程后终止

时间:2016-02-07 15:51:11

标签: c linux multithreading

所以,我在学校有一个项目,我们需要使用C和多线程等。我是C的新手,指针是如何工作的,所以我需要你的帮助。我写了程序,我执行它,然后创建两个或三个线程,然后说(核心转储)。另外,我通过valgrind运行它,它显然有一个空指针,但我无法解决它。下面是我通过valgrind运行时的代码和结果。

#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#define NUM_THREADS 5


struct thread_data{
   long  thread_id;
   };

  int SharedVariable = 0;
        void* SimpleThread(void *args) {

        struct thread_data *info = args;
        int num, val;
        for(num = 0; num < 20; num++) {
        if (random() > RAND_MAX / 2)
        usleep(500);
        val = SharedVariable;
        printf("*** thread %ld sees value %d\n", info->thread_id, val);
        SharedVariable = val + 1;
        }
        val = SharedVariable;
        printf("Thread %ld sees final value %d\n", info->thread_id, val);


        }

int main(int argc, char *argv[]){

   pthread_t threads[NUM_THREADS];
   int rc;
   long t;
   for(t=0; t<NUM_THREADS; t++){
      printf("In main: creating thread %ld\n", t);
      rc = pthread_create(&threads[t], NULL, SimpleThread, (void *)t);
      if (rc){
         printf("ERROR; return code from pthread_create() is %d\n", rc);
         exit(-1);
      }
   }

   /* Last thing that main() should do */
   pthread_exit(NULL);
} 

这是valgrind结果的一部分

==12412== Memcheck, a memory error detector
==12412== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al.
==12412== Using Valgrind-3.10.1 and LibVEX; rerun with -h for copyright info
==12412== Command: ./main
==12412== 
In main: creating thread 0
In main: creating thread 1
In main: creating thread 2
In main: creating thread 3
==12412== Thread 2:
==12412== Invalid read of size 8
==12412==    at 0x4007B3: SimpleThread (in /home/jovan/Desktop/Mttp1/main)
==12412==    by 0x4E3F181: start_thread (pthread_create.c:312)
==12412==    by 0x514F47C: clone (clone.S:111)
==12412==  Address 0x0 is not stack'd, malloc'd or (recently) free'd
==12412== 
==12412== 
==12412== Process terminating with default action of signal 11 (SIGSEGV): dumping core
==12412==  Access not within mapped region at address 0x0
==12412==    at 0x4007B3: SimpleThread (in /home/jovan/Desktop/Mttp1/main)
==12412==    by 0x4E3F181: start_thread (pthread_create.c:312)
==12412==    by 0x514F47C: clone (clone.S:111)
==12412==  If you believe this happened as a result of a stack
==12412==  overflow in your program's main thread (unlikely but
==12412==  possible), you can try to increase the size of the
==12412==  main thread stack using the --main-stacksize= flag.
==12412==  The main thread stack size used in this run was 8388608.
n main: creating thread 3
==12412== 
==12412== HEAP SUMMARY:
==12412==     in use at exit: 816 bytes in 3 blocks
==12412==   total heap usage: 3 allocs, 0 frees, 816 bytes allocated
==12412== 
==12412== LEAK SUMMARY:
==12412==    definitely lost: 0 bytes in 0 blocks
==12412==    indirectly lost: 0 bytes in 0 blocks
==12412==      possibly lost: 816 bytes in 3 blocks
==12412==    still reachable: 0 bytes in 0 blocks
==12412==         suppressed: 0 bytes in 0 blocks
==12412== Rerun with --leak-check=full to see details of leaked memory
==12412== 
==12412== For counts of detected and suppressed errors, rerun with: -v
==12412== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)

1 个答案:

答案 0 :(得分:2)

使用-g选项进行调试。

cc -g test.c 
Run the program and it will generate a core file
gdb ./a.out <core file generated>
When you run under gdb, you will get line number.

通过运行程序,我明白了。

Program terminated with signal 11, Segmentation fault.
#0  0x00000000004006da in SimpleThread (args=0x1) at thr.c:20
20              printf("*** thread %ld sees value %d\n", info->thread_id, val);

您传递的是从整数转换而来的(void *)。您需要将thread_data传递给pthread_create。

以下是修改后的程序:

#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#define NUM_THREADS 5


struct thread_data{
   long  thread_id;
   };

int SharedVariable = 0;
        void* SimpleThread(void *args) {

        struct thread_data *info = (struct thread_data *) args;
        int num, val;
        for(num = 0; num < 20; num++) {
        if (random() > RAND_MAX / 2)
        usleep(500);
        val = SharedVariable;
        printf("*** thread %ld sees value %d\n", info->thread_id, val);
        SharedVariable = val + 1;
        }
        val = SharedVariable;
        printf("Thread %ld sees final value %d\n", info->thread_id, val);


        }

int main(int argc, char *argv[]){

   pthread_t threads[NUM_THREADS];
   struct thread_data td[NUM_THREADS];
   int rc;
   long t;
   for(t=0; t<NUM_THREADS; t++){
      printf("In main: creating thread %ld\n", t);
      rc = pthread_create(&threads[t], NULL, SimpleThread, (void *)&td[t]);
      if (rc){
         printf("ERROR; return code from pthread_create() is %d\n", rc);
         exit(-1);
      }
   }

 /* Wait for the threads to end */
 for(t=0; t<NUM_THREADS; t++)
       pthread_join(threads[t], NULL);

   /* Last thing that main() should do */
   pthread_exit(NULL);
}