5.3 连接和分离线程

方法

pthread_join(thread, status)

pthread_detach(thread)

pthread_attr_setdetachstate(attr, detachstate)

pthread_attr_getdetachstate(attr)

连接

连接(joining)是一种线程之间完成同步的方法,举例如下。

pthread_join()方法会阻塞调用它的线程,直到相关的线程终止运行。如果相关线程调用了pthread_exit(),编程人员能够在主线程中获取相关线程终止时的具体信息(即pthread_exit()的参数会传递给pthread_join())。

一个线程只能被连接一次,对单个线程进行多次连接错误会导致逻辑错误。

用于线程间同步的另外两种方法:互斥量和条件变量将在后续章节中讲述。

能否连接

线程被创建时,它的一个属性决定其是能够被连接的或者是已经分离的,只有属性为能够被连接的线程才可以通过调用pthread_join() 对其进行连接。如果一个线程的属性为已分离的,那么它不能够被连接。

POSIX标准中要求创建的线程应该为可连接的。我们可以通过设置pthread_create()中的attr参数来设置创建线程时的这个属性,对attr的使用流程如下。

  • 声明一个pthread_attr_t类型的变量
  • 使用pthread_attr_init()对其初始化
  • 使用pthread_attr_setdetachstate()设置变量的可连接/分离属性
  • 变量使用结束后,使用pthread_attr_destroy()销毁该变量

分离

pthread_detach()方法用于显式地分离一个线程,即使它被创建时相关属性为可连接;没有对应的逆向操作的方法。

建议

如果一个线程需要被连接,在创建它时就设为可连接的属性。因为一些平台的实现中线程创建时可能属性的默认值不是可连接的,这样做代码的健壮性、可移植性更高。

如果事先确定一个线程永远不可能被连接,可以考虑将其初始化时的属性设为分离的,这样可以减少系统负载。

示例程序

复制代码
/*****************************************************************************
* FILE: join.c
* DESCRIPTION:
*   This example demonstrates how to "wait" for thread completions by using
*   the Pthread join routine.  Threads are explicitly created in a joinable
*   state for portability reasons. Use of the pthread_exit status argument is 
*   also shown. Compare to detached.c
* AUTHOR: 8/98 Blaise Barney
* LAST REVISED:  01/30/09
******************************************************************************/
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#define NUM_THREADS	4

void *BusyWork(void *t)
{
    int i;
    long tid;
    double result=0.0;
    tid = (long)t;
    printf("Thread %ld starting...\n",tid);
    for (i=0; i<1000000; i++)
        {
            result = result + sin(i) * tan(i);
        }
    printf("Thread %ld done. Result = %e\n",tid, result);
    pthread_exit((void*) t);
}

int main (int argc, char *argv[])
{
    pthread_t thread[NUM_THREADS];
    pthread_attr_t attr;
    int rc;
    long t;
    void *status;

    /* Initialize and set thread detached attribute */
    pthread_attr_init(&attr);
    pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);

    for(t=0; t<NUM_THREADS; t++) {
        printf("Main: creating thread %ld\n", t);
        rc = pthread_create(&thread[t], &attr, BusyWork, (void *)t); 
        if (rc) {
            printf("ERROR; return code from pthread_create() is %d\n", rc);
            exit(-1);
        }
    }

    /* Free attribute and wait for the other threads */
    pthread_attr_destroy(&attr);
    for(t=0; t<NUM_THREADS; t++) {
        rc = pthread_join(thread[t], &status);
        if (rc) {
            printf("ERROR; return code from pthread_join() is %d\n", rc);
            exit(-1);
        }
        printf("Main: completed join with thread %ld having a status of %ld\n",t,(long)status);
    }

    printf("Main: program completed. Exiting.\n");
    pthread_exit(NULL);
}

运行后输出信息如下

复制代码
Main: creating thread 0
Main: creating thread 1
Thread 0 starting...
Main: creating thread 2
Thread 1 starting...
Main: creating thread 3
Thread 2 starting...
Thread 3 starting...
Thread 1 done. Result = -3.153838e+06
Thread 0 done. Result = -3.153838e+06
Main: completed join with thread 0 having a status of 0
Main: completed join with thread 1 having a status of 1
Thread 3 done. Result = -3.153838e+06
Thread 2 done. Result = -3.153838e+06
Main: completed join with thread 2 having a status of 2
Main: completed join with thread 3 having a status of 3
Main: program completed. Exiting.
相关推荐
智者知已应修善业12 小时前
【51单片机数码管逐位显示1-8余位不亮】2024-10-23
c语言·经验分享·笔记·嵌入式硬件·51单片机
caimouse13 小时前
ReactOS 图形系统分析(47):GDI 批处理 — gdibatch.c
c语言·开发语言
caimouse14 小时前
ReactOS 窗口系统分析(1):窗口对象与创建 — window.c
c语言·开发语言
caimouse14 小时前
ReactOS 图形系统分析(53):系统库存对象 — stockobj.c
c语言·开发语言·spring
caimouse15 小时前
ReactOS 图形系统分析(52):OpenGL 支持 — wingl.c
c语言·开发语言
j7~15 小时前
【C语言】《C语言函数递归完全指南:思想、限制、经典例题(阶乘/斐波那契/青蛙跳台阶/汉诺塔)与迭代优化》
c语言·函数递归·汉诺塔问题·青蛙跳台阶问题·递归与迭代·n的阶乘
YSL07012417 小时前
动态内存管理
c语言
BreezeJuvenile17 小时前
基于C语言的SPSC环形缓冲区程序实现
c语言·环形缓冲区
SuperByteMaster17 小时前
recursive mutex的使用场景和场景代码
c语言
caimouse18 小时前
ReactOS 窗口系统分析(2):窗口类 — class.c
c语言·开发语言