目次
1. pthread_attr_init/pthread_attr_destroy (スレッド属性変数の初期化と破棄)
2. pthread_attr_setdetachstate、pthread_attr_getdetachstate (スレッドの分離属性の取得と設定)
3. ゾンビプロセスをシステムに回収させ、その終了値の API を取得する
(2) pthread_join、pthread_tryjoin_np (指定スレッドに参加)
1.スレッド関連プロパティのAPI
1. 糸の特殊性
2. スレッドのプロパティを設定する
3. 注意事項
- 上記の API はすべてスレッド属性操作用であり、スレッド属性は pthread_attr_t 型の変数です。
- スレッドのプロパティを設定するときは、上記の関数インターフェイスを介して型変数に必要なプロパティを追加し、pthread_create( ) の 2 番目のパラメーターを使用して、対応するプロパティを持つスレッドを作成します。
- 作成が成功する前に、スレッドのプロパティを設定する必要があります
次に、スレッド属性変数の使用
a. スレッド属性変数を定義し、pthread_attr_init( ) で初期化します。
b. pthread_attr_setXXX( ) を使用して、関連する属性を設定します。
c. スレッド属性変数を使用して、対応するスレッドを作成します。
d. pthread_attr_destroy( ) を使用して、スレッド属性変数を破棄します。
3. 関連する API
1. pthread_attr_init/pthread_attr_destroy (スレッド属性変数の初期化と破棄)
2. pthread_attr_setdetachstate、pthread_attr_getdetachstate (スレッドの分離属性の取得と設定)
知らせ
(1) スレッドはデフォルトで結合されています
(2) スレッドが結合されている場合、そのスレッドは終了時に自身のリソースを自動的に解放せず、ゾンビ プロセスになり、スレッドの終了値が他のスレッドによって取得される可能性があることを意味します。
(3) 特定のスレッドの終了値が不要な場合は、そのスレッドを切り離し状態にして、そのスレッドがゾンビプロセスにならないようにする
3. ゾンビプロセスをシステムに回収させ、その終了値の API を取得する
デフォルトでは、終了後、ゾンビプロセスになり、終了値を保持します
他のスレッドは、pthread_exit を介してシステムによってリソースを再利用することができ、終了値を取得することもできます
(1) pthread_exit (スレッドの終了)
デフォルトでは、終了後、ゾンビプロセスになり、終了値を保持します
他のスレッドは、pthread_exit を介してシステムによってリソースを再利用することができ、終了値を取得することもできます
(2) pthread_join、pthread_tryjoin_np (指定スレッドに参加)
注:
(1) スレッドの終了時に終了値がない場合は、retval を NULL として指定できます。(2) pthread_join( ) で指定されたスレッドがまだ実行中の場合、ブロックして待機します。
(3) pthread_tryjoin_np( ) で指定されたスレッドがまだ実行中の場合、すぐにエラーが返されます。
4番目に、属性コードを結合します
#include <stdio.h>
#include <stdio.h>
#include <unistd.h>
#include <pthread.h>
#include <stdlib.h>
#include <string.h>
void * func (void * arg)
{
while(1)
{
printf("这里是func线程,线程ID :%ld \n" , pthread_self() );
sleep(3);
break ;
}
int * p = calloc(1,4);
*p = 1024444 ;
// 退出本线程并设置返回值的地址(返回了num 的地址)
pthread_exit((void *)p); //返回的内存地址应该时一个堆空间
}
int main(int argc, char const *argv[])
{
// 创建线程
pthread_t t_id = -1 ;
pthread_create( &t_id , //新线程ID号
NULL , // 线程属性, NULL 默认属性
func, // 线程需要执行的例程(新线程需要执行的任务《函数》)
NULL ); // 线程的参数
printf("t_id : %ld\n" , t_id) ;
printf("这里是主函数,线程ID :%ld \n" , pthread_self() );
int * retval ;
// 阻塞等待接合线程
printf("等待 function 线程退出:\n");
pthread_join( t_id , (void*)&retval);
printf("结合线程成功, 退出值为:%d\n" , *retval);
// 尝试接合线程 (非阻塞)
// int ret_val = 0 ;
// if( ret_val = pthread_tryjoin_np( t_id , (void*)&retval))
// {
// fprintf(stderr , "接合失败:%s\n" , strerror(ret_val));
// }
return 0;
}
スレッドが終了する場合、終了値は *p の値です
5.分離属性の糸の組み合わせ
#include <stdio.h>
#include <stdio.h>
#include <unistd.h>
#include <pthread.h>
#include <stdlib.h>
#include <string.h>
void * func (void * arg)
{
while(1)
{
printf("这里是func线程,线程ID :%ld \n" , pthread_self() );
sleep(3);
break ;
}
int * p = calloc(1,4);
*p = 1024444 ;
// 退出本线程并设置返回值的地址(返回了num 的地址)
pthread_exit((void *)p); //返回的内存地址应该时一个堆空间
}
int main(int argc, char const *argv[])
{
// 创建线程属性变量
pthread_attr_t attr ;
// 初始化线程属性
pthread_attr_init(&attr);
// 设置属性信息 (分离属性)
if(pthread_attr_setdetachstate(&attr,PTHREAD_CREATE_DETACHED))
{
printf("设置分离属性失败!!\n");
}
else{
printf("设置分离属性成功!!\n");
}
// 创建线程
pthread_t t_id = -1 ;
pthread_create( &t_id , //新线程ID号
&attr , // 线程属性(当前设置为分离)
func, // 线程需要执行的例程(新线程需要执行的任务《函数》)
NULL ); // 线程的参数
printf("t_id : %ld\n" , t_id) ;
printf("这里是主函数,线程ID :%ld \n" , pthread_self() );
int * retval ;
int ret_val = 0 ;
// 阻塞等待接合线程
printf("等待 function 线程退出:\n");
if(ret_val = pthread_join( t_id , (void*)&retval))
{
fprintf(stderr , "接合失败:%s\n" , strerror(ret_val));
return -1 ;
}
printf("结合线程成功, 退出值为:%d\n" , *retval);
// 尝试接合线程 (非阻塞)
// int ret_val = 0 ;
// if( ret_val = pthread_tryjoin_np( t_id , (void*)&retval))
// {
// fprintf(stderr , "接合失败:%s\n" , strerror(ret_val));
// }
return 0;
}
出力: バインドに失敗しました: 無効な atgument
個別の属性として設定され、組み合わせることはできません