学习OpenMP的copyin中的小疑问

int COPYIN_A = 100;
#pragma omp threadprivate(COPYIN_A)  
void TestCopyin2()
{
    omp_set_num_threads(4);
#pragma omp parallel
    {
        printf("No.%d - Initial COPYIN_A = %d\n", omp_get_thread_num(), COPYIN_A);
        COPYIN_A = omp_get_thread_num();
        printf("get threadNo COPYIN_A: %d\n", COPYIN_A);
    }
    printf("Global COPYIN_A: %d\n\n", COPYIN_A);

#pragma omp parallel copyin(COPYIN_A)            // copyin
    {
        printf("No.%d - Initial COPYIN_A = %d\n", omp_get_thread_num(), COPYIN_A);
        COPYIN_A = omp_get_thread_num();
        printf("get threadNo COPYIN_A: %d\n", COPYIN_A);
    }
    printf("Global COPYIN_A: %d\n\n", COPYIN_A);

#pragma omp parallel                // Will not copy, to check the result.
    {
        printf("No.%d - Initial COPYIN_A = %d\n", omp_get_thread_num(), COPYIN_A);
        COPYIN_A = omp_get_thread_num();
        printf("get threadNo COPYIN_A: %d\n", COPYIN_A);
    }
    printf("Global COPYIN_A: %d\n", COPYIN_A);
}

为什么每一段的Global COPYIN_A的值永远等于0?为什么第三段COPYIN_A的赋值在输出之后,但输出的COPYIN_A值与后面的赋值之后的COPYIN_A值一致?

img

第一段,初始值是人为给定的100,结束值为线程号;
输出 Global 的语句,没在并行域中,因此是主线程执行,输出主线程的值;
第二段,使用了copyin,每个线程的初始值等于主线程的值,也就是 0;结束后,各个线程的值等于线程号;
第三段,初始值为线程号,是第二段修改的。

threadprivate用来指定全局的对象被各个线程各自复制了一个私有的拷贝,即各个线程具有各自私有的全局对象。只能用于copyin,copyprivate,schedule,num_threads和if子句中。
那么
第一段中threadprivate没有起效果,是一个简单的竞态状态下的并行,不应该是最后一次赋值的线程号吗,为什么每一次的计算结果都是0?这里只是一个简单的输出,不是获取主线程号的函数输出!
第二段中copyin语句,符合预期结果,只有global输出和第一段是一个疑问。
第三段中threadprivate应该也没有起效果。理论上并行创建的线程不应该在并行结束之后就释放掉了吗?还是说threadprivate下线程不释放了?不然为什么说第三段前面输出的是第二段的初始值。

threadprivate 可以看看这个视频,有详细解答: Fortran多核并行计算_哔哩哔哩_bilibili OpenMP编程基础 https://www.bilibili.com/video/BV1uA411v776?p=5
1、你怎么会认为第一段中threadprivate没起效果呢?
2、输出 Global 的语句,没在并行域中,因此是主线程执行,输出主线程的值;这一点与 private有区别:private并行域中线程0的值不会影响并行域外的主线程,threadprivate并行域中线程0与并行域外的主线程是同一个地址;
3、线程会释放,但threadprivate变量会保留,不然跟private何异?

谢谢,明白了