Linux多線程編程並傳遞多個參數實例


例子詳細解析:

一. pthread_create()與pthread_join()函數

1 #include <pthread.h>
2 int pthread_join(pthread_t thread,
3                         void **retval);

 

1. pthread_join函數作用

   pthread_join函數作用是在一個線程中以阻塞的方式等待另一個線程(線程標識符為thread)的退出。如果等待的進程已經結束,那么該函數會立即返回。

    retval是用戶定義的指針,用來存儲被等待線程的返回值

    返回值: 0 -- 成功,失敗 -- 錯誤號errno

2. pthread_join的應用

    使一個線程等待另一個線程的結束

    代碼中如果沒有pthread_join主線程會很快結束,從而從而合整個進程線束,從而使創建的線程沒有機會執行就結束了,在主線程加入pthread_join后,主線程會阻塞等待直到(被等待的)線程結束后,主線程自己才結束,從而使創建的線程有機會執行

3. 一個線程不能被多個線程等待,否則第一個接收到信號的線程成功返回,其余調用 pthread_join 的線程則返回錯誤代碼ESRCH。

 

1 #include <pthread.h>
2 int pthread_create(pthread_t *thread, 
3                             const pthread_attr_t *attr,
4                             void *(*start_routine) (void *), 
5                             void *arg);

1. pthread_create函數的作用

   創建一個線程,成功時返回0,錯誤時返回errno。

   thread:被創建線程的標識符,pthread_join使用這個標識符來等待該線程的結束。

   attr:     設置線程的屬性,可以為NULL

   第三個參數是線程函數的入口地址

   arg:      傳遞給線程的參數,當要傳遞給線程的參數有多個時,可以使用結構體.

具體例子
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif

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

// 參數結構體 
struct argument
{
  int num;
  char string[30];
};

// 聲明兩個線程函數
void *thread1_func( void * );
void *thread2_func( void * );

int main(int argc, char *argv[])
{
  //定義兩個線程標識符
  pthread_t thread1, thread2;
  //定義用來接收兩個線程退出后的返回值,用作pthread_join的第二個參數
  void *thread1_return, *thread2_return;
  //傳遞的參數結構體
  struct argument arg1, arg2;
  int i;
  int wait_thread_end; //判斷線程退出成功與否
  //參數結構體值初始化
  arg1.num = 1949;
  strcpy( arg1.string, "中華人民共和國" );
  
  arg2.num = 2012;
  strcpy( arg2.string, "建國63周年" );
  
  // 創建兩個線程
  pthread_create(&thread1, NULL, thread1_func, (void*)&arg1 );
  pthread_create( &thread2, NULL, thread2_func, (void*)&arg2 );
  
  for( i = 0; i < 2; i++ )
  {
    printf("我是最初的進程!\n");
    sleep(2);  //主統線程睡眠,調用其他線程
  }
  
  //等待第一個線程退出,並接收它的返回值(返回值存儲在thread1_return)
  wait_thread_end = pthread_join( thread1, &thread1_return );
  if( wait_thread_end != 0 ) 
  {
    printf("調用 pthread_join 獲取線程1的返回值出現錯誤!\n");
  }
  else
  {
    printf("調用 pthread_join 成功!線程1退出后的返回值是 %d\n", (int)thread1_return);
  }
  
  //等待第二個線程退出,並接收它的返回值(返回值存儲在thread2_return)
  wait_thread_end = pthread_join( thread2, &thread2_return);
  if( wait_thread_end != 0 ) 
  {
    printf("調用 pthread_join 獲取線程2的返回值出現錯誤!\n");
  }
  else
  {
    printf("調用 pthread_join 成功!線程2退出后的返回值是 %d\n",(int)thread2_return );
  }

  return EXIT_SUCCESS;
}

/**
 *線程1函數實現 
 */
 void *thread1_func( void *arg )
{
  int i;
  struct argument *arg_thread1; // 接收傳遞過來的參數結構體
  
  arg_thread1 = ( struct argument * )arg;
  
  for( i = 0; i < 3; i++)
  {
    printf( "我來自線程1,傳遞給我的參數是 %d, %s\n", arg_thread1->num, arg_thread1->string);
    sleep(2); // 投入睡眠,調用其它線程
  }
  return (void *)123;
}

 void *thread2_func( void *arg )
{
  int i;
  struct argument *arg_thread2; // 接收傳遞過來的參數結構體
  
  arg_thread2 = ( struct argument * )arg;
  
  for( i = 0; i < 3; i++)
  {
    printf( "我來自線程2,傳遞給我的參數是 %d, %s\n", arg_thread2->num, arg_thread2->string);
    sleep(2); // 投入睡眠,調用其它線程
  }
  return (void *)456;
}

例子中要請注意的地方:

 void *thread1_func( void *arg )

  {

    ...

    return (void*)123;

  }

   void *thread2_func( void *arg )

  {

    ...

    return (void*)456;

  }

1. 在線程函數中thread1_func()和thread2_func()中,最后一句return語句中,對返回的值要進行類型轉換(轉換成(void *)),返回值的類型要與線程函數的聲明和定義的返回值類型一致。

2.  兩個線程函數的返回值均為一個指針(把一個整數轉換成(void*)返回)。該指針存儲在pthread_join()的第三個參數中,在這兩個函數中等價於

    &thread1_return = thread1_func((void*)&arg1);

   &thread2_return = thread2_func((void*)&arg2);

   其中,&thread1_return是pthread_join的第二個參數,在前面函數解析中說過,pthread_join(phtread_t thread, void **retval)函數的第二個參數retval可以存儲線程的返回值。該返回值直接存儲在&thread1_return和&thread2_return,此時thread1_return和thread2_return值就是線程1和線程2函數的返回值(void *)類型。所以(int)thread1_return和(int)thread2_return就是該函數的返回值內容。由定義(void *thread1_return, *thread2_return)可以看出,thread1_return和thread2_return中兩個指針,也就是說,這兩個指針所存儲的地址已經被兩個線程的返回值所覆蓋。

 

 

 

  

 

 

 

 

 

 

 

 

 

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM