日期:2014-05-16  浏览次数:20761 次

linux 线程需要注意地方
1.线程创建函数:

       int pthread_create(pthread_t *restrict thread,  const pthread_attr_t *restrict attr,
      void *(*start_routine)(void*), void *restrict arg);

       我们知道第一个参数线程ID是传出参数,以便调用它的线程能获取其创建线程的ID,根据线程ID所相应的处理,最后一个参数是传入参数,创建的线程可以获取它做相应操作。

       1.我们是否能在创建的线程使用线程ID变量:thread?
        当然不能,使用它存在一定的风险,调用它的线程把创建的线程的ID存放在thread中,不过由于thread是一个传出参数,如果新线程在创建线程返回之前就运行了,那么新线程看到thread的值是未初始化的内容,这个内容并不是正确的 线程ID的内容。一般在创建线程中使用pthread_self(),获取当前创建线程的ID。

       2 传入参数需要注意的地方,从以下程序来分析:
        代码一:

       
  
        #include <stdio.h>
        #include <pthread.h>

         void*  start_thread(void *param) 
         { 
               char *str = (char *)param; 
               printf("s:%s\n",__func__, str);
               return NULL; 
         } 

         pthread_t create_test_thread(char * buf) 
         { 

              pthread_t id =0; 
              pthread_create(&id, NULL, start_thread,buf); 
              return id; 
         } 

         int main(void) 
         { 
               void *ret = NULL; 
               char buf[] ="helloword"; 
               pthread_t id = create_test_thread(buf); 
               pthread_join(id,&ret);  
               return 0; 
          } 

      
         代码二:
         
  
        #include <stdio.h>
        #include <pthread.h>

         void*  start_thread(void *param) 
         { 
               char *str = (char *)param; 
               printf("s:%s\n",__func__, str);
               return NULL; 
         } 

         pthread_t create_test_thread() 
         { 

              pthread_t id =0; 
              char buf[] ="hello world"; 
              pthread_create(&id, NULL, start_thread,buf); 
              return id; 
         } 

         int main(void) 
         { 
               void *ret = NULL; 
               pthread_t id = create_test_thread(); 
               pthread_join(id,&ret);  
               return 0; 
          } 


         代码三:
        
  
        #include <stdio.h>
        #include <pthread.h>

         void*  start_thread(void *param) 
         { 
               char *str = (char *)param; 
               printf("s:%s\n",__func__, str);
               return NULL; 
         } 

         pthread_t create_test_thread(char * buf) 
         { 

              pthread_t id =0; 
              pthread_create(&id, NULL, start_thread,buf); 
              return id; 
         } 

         int main(void) 
         { 
               void *ret = NULL; 
               char buf[] ="helloword"; 
               pthread_t id = create_test_thread(buf); 
               return 0; 
          } 

       
        我们用gcc -o mythread mythread.c -lpthread,并运行./mythread,我们只能从代码一中获取正确的结果,为什么呢?
         代码二中:buf的作用域只限于函数create_test_thread()中,函数执行完毕,buf所指向的空间也就释放了,如果主函数执行完毕,创建线程还没启动,那么创建线程使用的buf就是一块不可靠内存,可能产生无法预料的错误。
         对于代码三:同样原理,可能创建的线程还没执行,主线程已经运行完毕,那么整个进程已经结束了,当然就得不到想要的结果。
         所以我们要在创建的线程,使用主线程传过来参数,需要确保创建线程能够启动,同时获取变量内存空间还没释放。
         

        
<