乡下人产国偷v产偷v自拍,国产午夜片在线观看,婷婷成人亚洲综合国产麻豆,久久综合给合久久狠狠狠9

  • <output id="e9wm2"></output>
    <s id="e9wm2"><nobr id="e9wm2"><ins id="e9wm2"></ins></nobr></s>

    • 分享

      Linux?多線程編程(?POSIX?)(?一?)?1.基礎(chǔ)線程創(chuàng)建:

       春華_秋實 2012-05-02

      Linux 多線程編程( POSIX )( 一 ) ---->  代碼區(qū)

      (2012-01-30 17:07:29)
      標(biāo)簽:

      雜談

      分類: Linux進程與線程
      1.基礎(chǔ)線程創(chuàng)建:

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

      void * print_id( void * arg )        //!> 這是線程的入口函數(shù)                               
      {
          printf("The Current process is: %d \n", getpid());                                //!> 當(dāng)前進程ID   
          printf( "The Current thread id : %d \n", (unsigned)pthread_self() );    //!> 注意此處輸出的子線程的ID
      }

      int main( )
      {
          pthread_t        t;
          int                 t_id;
         
          t_id = pthread_create( &t, NULL, print_id, NULL );        //!> 簡單的創(chuàng)建線程
         
          if( t_id != 0 )                        //!> 注意創(chuàng)建成功返回0                               
          {
              printf("\nCreate thread error...\n");
              exit( EXIT_FAILURE );
         
          sleep( 1 );
          printf("\nThe Current process is: %d \n", getpid());                         //!> 當(dāng)前進程ID       
          printf( "The Main thread id : %d \n", (unsigned)pthread_self() );    //!> 注意輸出的MAIN線程的ID
          return 0;
      }



      2.測試線程的創(chuàng)建和退出

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

      void * entrance_1( void * arg )                //!> 第一個創(chuàng)建的線程的入口函數(shù)
      {
          printf( " thread 1 id == %d , run now ... \n", ( unsigned )pthread_self() );
          sleep( 3 );
          return ( ( void * ) 1 );
      }

      void * entrance_2( void * arg )                //!> 第二個創(chuàng)建的線程的入口函數(shù)
      {
          printf( " thread 2 id == %d , run now ... \n", ( unsigned )pthread_self() );
          sleep( 3 );
          return ( ( void * ) 2 );
      }

      int main( )
      {
          pthread_t        t1 = -1;    //!> 最好是初始化:因為下面的pthread_join是需要判斷是否成功在輸出的
          pthread_t        t2 = -1;
          int              tid1;
          int              tid2;
          void           ret;
         
          tid1 = pthread_create( &t1, NULL, entrance_1, NULL );    //!> 簡單的創(chuàng)建線程
          tid2 = pthread_create( &t2, NULL, entrance_2, NULL );
         
          if( tid1 != 0 || tid2 != 0 )    //!> 創(chuàng)建線程失敗                   
          {
              printf( "Create thread error...\n" );
              exit( EXIT_FAILURE );
          }
         
          if( t1 != -1 )                //!> 也就是線程還沒有結(jié)束
          {
              if ( pthread_join( t1, &ret ) == 0 )    //!> join success
              {
                  printf( " thread 1 get the return of pthread_join == %d \n", 2 );/ )
       {
           pthread_mutex_init( &mutex, NULL );        //!> 初始化為默認(rèn)的互斥鎖
          
           printf("主函數(shù):創(chuàng)建2個子線程...\n");
          
           create_two_thread();        //!> 創(chuàng)建2個線程
          
           printf("主函數(shù):等待線程完成任務(wù)...\n");
          
           wait_two_thread();        //!> 等待線程完成任務(wù)
                                       //!> 線程任務(wù)完成才可以執(zhí)行下面代碼
           printf("線程任務(wù)完成...\n");
          
           printf("Num == %d \n\n", num);
          
           return 0;
       }
       
      4.雙線程處理:冒泡排序算法

      //        雙線程處理冒泡排序(多線程也一樣)
      //        實現(xiàn)從“小”--->“大”排序

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

      int g_arr[] = { 10, 23, 12, 34, 5, 29, 90, 9, 78, 44 };        //!> 全局的要排序的數(shù)組
      pthread_t                thread[2];               //!> 兩個線程
      pthread_mutex_t        mutex;                //!> 互斥鎖

      int                         g_i = 0;                     //!> 全局的剩余排列次數(shù)

      //!> 打印數(shù)組
      void print_array()
      {
          int i;
          for( i = 0; i < 10; i++ )
          {
              printf( " %d ", g_arr[i] );
          }
          printf("\n");
      }

      //!> 交換元素
      void swap_elem( int * a, int * b )
      {
          int temp;
          temp = *a;
          *a = *b;
          *b = temp;
      }

      //!> 線程1入口函數(shù)
      void * entrance_1( void * arg )
      {
          int j;
          for( g_i = 0; g_i < 10; g_i++ )    //!> 外層循環(huán)
          {
              pthread_mutex_lock( &mutex );        //!> 加鎖
             
              printf( "線程1后臺執(zhí)行排序...\n" );
             
              for( j = 0; j < ( 10 - g_i - 1 ); j++ )    //!> 內(nèi)層循環(huán)
              {
                  if( g_arr[j] > g_arr[j+1] )
                  {
                      swap_elem( &g_arr[j], &g_arr[j+1] );
                  }
              }
             
              pthread_mutex_unlock( &mutex );    //!> 解鎖
             
              sleep( 1 );
          }
      }

      //!> 線程2入口函數(shù)
      void * entrance_2( void * arg )
      {
          int j;
          for( g_i = 0; g_i < 10; g_i++ )    //!> 外層循環(huán)
          {
              pthread_mutex_lock( &mutex );        //!> 加鎖
             
              printf( "線程2后臺執(zhí)行排序...\n" );
                 
              for( j = 0; j < ( 10 - g_i - 1 ); j++ )    //!> 內(nèi)層循環(huán)
              {
                  if( g_arr[j] > g_arr[j+1] )
                  {
                      swap_elem( &g_arr[j], &g_arr[j+1] );
                  }
              }
         
              pthread_mutex_unlock( &mutex );    //!> 解鎖

              sleep( 2 );   
          }
      }

      //!> 創(chuàng)建2個線程
      void create_two_thread()
      {
          memset( &thread, 0, sizeof( thread ) );            //!> 初始化為0(作為下面的判斷進程是否創(chuàng)建OK依據(jù))
         
          if( ( pthread_create( &thread[0], NULL, entrance_1, NULL ) ) == 0 )
          {
              printf("線程1創(chuàng)建OK ...\n");
          }
          else
          {
              printf("線程1創(chuàng)建Error ...\n");
              exit( EXIT_FAILURE );
          }
         
          if( ( pthread_create( &thread[1], NULL, entrance_2, NULL ) ) == 0 )
          {
              printf("線程2創(chuàng)建OK ...\n");
          }
          else
          {
              printf("線程2創(chuàng)建Error ...\n");
              exit( EXIT_FAILURE );
          }
         
      }

      //!> 線程執(zhí)行與等待
      void do_and_wait()
      {
          if( thread[0] != 0 )//!> 由于在create_two_thread中初始化=0,if床架ok,那么不可能還是0
          {
              pthread_join( thread[0], NULL );    //!> 等待線程1結(jié)束,不結(jié)束不執(zhí)行下面代碼
              printf("線程1執(zhí)行結(jié)束退出...\n");
          }
          else
          {
              printf("線程1創(chuàng)建Error...\n");
              exit( EXIT_FAILURE );
          }
         
          if( thread[1] != 0 )
          {
              pthread_join( thread[1], NULL );    //!> 等待線程1結(jié)束,不結(jié)束不執(zhí)行下面代碼
              printf("線程2執(zhí)行結(jié)束退出...\n");
          }
          else
          {
              printf("線程2創(chuàng)建Error...\n");
              exit( EXIT_FAILURE );
          }
         
      }

      int main( )
      {
          printf("主函數(shù):下面創(chuàng)建2個線程共同處理冒泡排序...\n");
         
          pthread_mutex_init( &mutex, NULL );
         
          print_array();                //!> 打印排序前的結(jié)果
         
          create_two_thread();        //!> 創(chuàng)建線程
          do_and_wait();            //!> 執(zhí)行線程and等待
         
          printf( "排序完成:\n" );

          print_array();                //!> 打印排序后的結(jié)果
             
          return 0;
      }

      5.線程清理處理程序

      //        線程清理處理程序TEST

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

      void clean(void *arg)
      {
          printf("清理: %s \n", (char *)arg);
      }

      void * entrance( void * arg )
      {
          printf("線程開始...\n");
         
          pthread_cleanup_push( clean, "線程處理程序1" );
          pthread_cleanup_push( clean, "線程處理程序2" );
         
          printf("pthread clean 完成...\n");
         
          sleep(3);
         
          pthread_exit((void *)0);        //!> 我們知道:清理函數(shù)只有在異常退出時候才會做一些清理工作
                                                      //!> 所以此處的退出是異常退出來測試的!
         
          pthread_cleanup_pop(0);    
          pthread_cleanup_pop(0);    
         
         
         
      }

      int main( )
      {
          pthread_t     tid;
          void        ret = NULL;
         
          if( ( pthread_create( &tid, NULL, entrance, (void *)1 ) ) != 0 )
          {
              printf("創(chuàng)建線程失敗...\n");
              exit( EXIT_FAILURE );
          }
         
          pthread_join( tid, &ret );       
         
          if( ret )                            //!> 注意此處相當(dāng)于是拋出異常
                                        //!> 避免子線程的異常退出造成的空指針情況
              printf( "結(jié)束:code == %d\n", *( ( int * ) ret) );
          }
         
          return 0;
      }

      /////////////////////////////////////////////////////////////
      //    DEMO——2

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

      void clean( void * arg )
      {
          printf("清理函數(shù)執(zhí)行...\n");
      }

      void * entrance( void * arg )
      {
          int old_type, old_state;
          int i = 0;
         
          pthread_cleanup_push( clean, NULL );    //!> 設(shè)置清理函數(shù)
          printf("下面設(shè)置對本線程的“取消”無效\n");
          pthread_setcancelstate( PTHREAD_CANCEL_DISABLE, &old_state );
                                                      //!> 設(shè)置對本線程的“取消”無效
          pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS,&old_type);    //>>>>>>>>>>> 目標(biāo)句1
         
          while( 1 )
          {
              ++i;
              printf("子線程runing...\n");
              sleep( 2 );
              if( 5 == i )
              {
                  printf("下面取消設(shè)置對本線程的“取消”無效\n");
                  pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, &old_state);
              }
          }
         
          pthread_cleanup_pop( 0 );
      }

      int main( int argc, char ** argv )
      {
          pthread_t    tid;
          int               res;
          void *          ret;
         
          pthread_create( &tid, NULL, entrance, NULL );
          sleep( 2 );
          printf("請求子線程退出...\n");
          pthread_cancel( tid );            //!> 請求子線程退出
         
          res = pthread_join( tid, &ret );    //!> 等待子線程退出
         
          if( ret != PTHREAD_CANCELED )    //!> 非安全退出
          {
              printf("pthread_join 失敗...\n");
              exit( EXIT_FAILURE );
          }
          else
          {
              printf("Success..");
          }
             
          exit( EXIT_SUCCESS );   
      }


          分析:
              沒有加上“目標(biāo)句”的結(jié)果是:
                                              下面設(shè)置對本線程的“取消”無效
                                              子線程runing...
                                              請求子線程退出...
                                              子線程runing...
                                              子線程runing...
                                              子線程runing...
                                              子線程runing...
                                              下面取消設(shè)置對本線程的“取消”無效
                                              子線程runing...                        //!> 比下面多的
                                              清理函數(shù)執(zhí)行...
                                              Success..                                //!> 與下面不一樣的
                                             
            加上后:
                                              下面設(shè)置對本線程的“取消”無效
                                              子線程runing...
                                              請求子線程退出...
                                              子線程runing...
                                              子線程runing...
                                              子線程runing...
                                              子線程runing...
                                              下面取消設(shè)置對本線程的“取消”無效
                                              清理函數(shù)執(zhí)行...
                                              pthread_join 失敗...                    //!> 與上面不一樣的
                                             
             這句的作用是將取消類型設(shè)置為PTHREAD_CANCEL_ASYNCHRONOUS,即取消請求會被立即響應(yīng)                                   
             那么就不會再次進入等待下一個“取消點”再進行取消?。。?BR>   
             注意:if在while中沒有sleep,那么程序會無限r(nóng)un,我們知道sleep是相當(dāng)于是釋放一下線程,那么此時的主線程中的cancel信號又被接收到,那么if本函數(shù)可以響應(yīng)了,那么就cancle了,if將sleep去掉,那么死循環(huán)!再次解釋:所謂pthread_cancel僅僅是請求某個線程退出,那么究竟是不是退出還要看state和type的設(shè)置!                   



      6. pthread_once 工作原理code


      //        pthread_once 函數(shù)使用

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

      pthread_once_t        once = PTHREAD_ONCE_INIT;    //!> once宏賦值

      //!> 初始化執(zhí)行函數(shù)
      void once_init( void )
      {
          printf("初始化成功! 我的ID == %d\n", (unsigned)pthread_self());
      }

      //!> 線程入口函數(shù)
      void * entrance( void * arg )
        
          printf("子線程:ID == %d \n", (unsigned)pthread_self());
          //!> once = PTHREAD_ONCE_INIT;        //!> 測試使用(下面的要求)
          pthread_once( &once, once_init );        //!> 此處也有初始化
      }

      //!> main函數(shù)
      int main( int argc, char * argv[] )
      {
          pthread_t        pid;
         
          pthread_create( &pid, NULL, entrance, NULL );

          printf("主函數(shù)ID == %d \n", (unsigned)pthread_self());
         
      //!>    pthread_join( pid, NULL );            //!> 分析點
         
          pthread_once( &once, once_init );    //!> 調(diào)用一次初始化函數(shù)
         
          pthread_join( pid, NULL );
         
          return 0;
      }

              if pthread_join是在主函數(shù)初始化后面,那么就是主函數(shù)初始化的
              結(jié)果是: 主函數(shù)ID == 441960192
                             初始化成功! 我的ID == 441960192
                            子線程:ID == 433944320
              顯而易見是主函數(shù)初始化的!
             
              if pthread_join是在之前,那么就是要等待子函數(shù)執(zhí)行ok后才執(zhí)行自己的下面代碼
              但是此時已經(jīng)初始化ok了,所以不在初始化!
              結(jié)果是:主函數(shù)ID == 210818816
                            子線程:ID == 202802944
                            初始化成功! 我的ID == 202802944
              顯然是子函數(shù)執(zhí)行的初始化!

              本質(zhì):   其實就是操作once變量而已,與互斥變量的本質(zhì)是一樣的?。。?BR>                      我們可以這樣測試在entrance中加入once = PTHREAD_ONCE_INIT;
              結(jié)果是:主函數(shù)ID == 1590228736
                            初始化成功! 我的ID == 1590228736
                            子線程:ID == 1582212864
                            初始化成功! 我的ID == 1582212864
             
              感興趣的可以使用pthread_mutex_t 的互斥變量處理,效果一樣!
              還有最最簡單的就是bool值處理!此處不建議!

      7.pthread_key_create線程鍵 與線程存儲

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

      pthread_once_t        once = PTHREAD_ONCE_INIT;
      pthread_key_t        key;            //!> 鍵值
         
      int                         g_val = 10;    //!> 傳說中的獨享值,呵呵

      void once_init_key()
        
          if( pthread_key_create( &key, NULL ) == 0 )    //!> 創(chuàng)建線程鍵值
                                                            //!>
              printf("創(chuàng)建線程鍵OK ...\n");
          }
      }

      void * entrance( void * arg )
      {
          int * val;
          printf("子線程:ID == %d \n", (unsigned)pthread_self());
         
          pthread_setspecific( key, &g_val );               //!> 將 g_val 作為一個每個進程的獨享值
         
          val = ( int * )pthread_getspecific( key );        //!> 取出那個值
                                                              //!> 此后對于這些量都有自己的處理方式,
                                                              //!> 名稱相同但是內(nèi)容不同?。?!   
                                                              //!> 對于文件的處理是最好的?。?!
          printf("ID == %d, Value == %d\n",  (unsigned)pthread_self(), *val);
      }


      int main( )
      {
          pthread_t        tid, tid2;
          void         ret1;
          void        ret2;
         
          if( pthread_create( &tid, NULL, entrance, NULL ) != 0 )            //!> 線程1
          {
              printf("創(chuàng)建線程1失敗...\n");
              exit( EXIT_FAILURE );
          }
         
          if( pthread_create( &tid2, NULL, entrance, NULL ) != 0 )            //!> 線程2
          {
              printf("創(chuàng)建線程2失敗...\n");
              exit( EXIT_FAILURE );
          }
                 
          printf("主函數(shù):ID == %d \n", (unsigned)pthread_self());
             
          //!>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>   
         
          pthread_once( &once, once_init_key );    //!> 創(chuàng)建一個鍵值
         
          //!>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
         
          printf("下面等待子線程執(zhí)行ok... \n");
         
          pthread_join( tid, &ret1 );                    //!> 等待線程( 必不可少 )
          pthread_join( tid2, &ret2 );
         
          return 0;
      }

      結(jié)果:
          主函數(shù):ID == 1588877056
          創(chuàng)建線程鍵OK ...
          子線程:ID == 1580861184
          ID == 1580861184, Value == 10
          下面等待子線程執(zhí)行ok...
          子線程:ID == 1572468480
          ID == 1572468480, Value == 10

        本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊一鍵舉報。
        轉(zhuǎn)藏 分享 獻花(0

        0條評論

        發(fā)表

        請遵守用戶 評論公約

        類似文章 更多