线程 11 | 线程标识、线程创建、线程终止

pthread_self函数

功能:获取线程ID。

pthread_t pthread_self(void);

                             返回值:若成功,返回0;否者,返回错误编号
  • 线程ID:pthread_t类型,本质:在Linux为无符号整数(%lu),其他系统是结构体实现
  • 线程ID是进程内部识别标志。(两个进程间,线程ID允许相同)

注意:不应使用全局变量pthread_t tid,在子线程通过pthread_create传出参数来获取线程ID,而应使用pthread_self.

pthread_create函数

功能:创建一个新线程

typedef void *(*start_routine) (void *);
int pthread_create(pthread_t *thread, const pthread_attr_t *attr, start_routine th_fn, void *arg);


                                                             返回值:若成功,返回0;否者,返回错误编号

参数:

  • pthread_t:当前Linux可理解为:typedef unsigned long int pthread_t;
  • 参数1:传出参数,保存系统为我们分配好的线程ID
  • 参数2:通常传NULL,表示使用线程默认属性。若想使用具体属性也可以修改该参数。
  • 参数3:函数指针,指向线程主函数(线程体),该函数运行结束,则线程结束。
  • 参数4:线程执行期间所使用的参数。

测试代码:

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

void *thrd_func(void *arg)
{
    printf("thread id = %lu, pid = %u\n", pthread_self(), getpid());
    return NULL;
}


int main(void)
{
    pthread_t tid;
        int ret; 
    
    printf("In main 1: thread id = %lu, pid = %u\n", pthread_self(), getpid());

    ret = pthread_create(&tid, NULL, thrd_func, NULL);
    if(ret != 0) {
        printf("pthread_create error\n");
        exit(1);
    }
        
    printf("In main2: thread id = %lu, pid =%u\n", pthread_self(), getpid());
        sleep(1);
    return 0;
}

输出结果:

测试代码:

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

void *thrd_func(void *arg)
{
    int i = (int) arg;
    sleep(i);
    printf("%dth thread: id = %lu, pid = %u\n", i+1, pthread_self(), getpid());
    return NULL;
}

int main(void)
{
    pthread_t tid;
        int ret, i; 
        
    for(i = 0; i < 5; i++) {
        ret = pthread_create(&tid, NULL, thrd_func, (void *)i);
        if(ret != 0) {
            fprintf(stderr, "pthread_create%s\n", strerror(ret));
                exit(1);
        }
    }
    
    sleep(i);
    return 0; //将当前进程退出 
}

输出结果:

线程与共享

注意:线程间共享全局变量!

【牢记】线程默认共享数据段、代码段等地址空间,常用的是全局变量,而进程间不共享变量,只能借助mmap。

线程共享资源:

  • 文件描述符
  • 每种信号的处理方式
  • 当前工作目录
  • 用户ID和组ID
  • 内存地址空间(.text/ .data/ .bss/heap/共享库)

线程非共享资源

  • 线程ID
  • 处理器现场和栈指针(内核栈)
  • errno变量
  • 信号屏蔽字

测试代码:

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

int var = 100;

void *tfn(void *arg)
{
    var = 200;
    printf("thred\n");
    return NULL;
}

int main(void)
{
    printf("At first var = %d\n", var);
    pthread_t tid;
    pthread_create(&tid, NULL, tfn, NULL);
    sleep(1);
    
    printf("after pthread_create, var = %d\n", var);
    
    return 0;
 } 

输出结果:

pthread_exit函数

功能:将单个线程退出

void pthread_exit(void *retval)  参数:retval表示线程退出状态,通常NULL

pthread_join函数

int pthread_join(pthread_t thread, void **retval);

                                 返回值:若成功,返回0,否则,返回错误编号

参数:

  • thread:线程ID(【注意】:不是指针);retval:存储线程结束状态

注意:

  • 调用该函数的线程将挂起等待,直到id为thread的线程终止状态。thread线程以不同的方法终止,通过pthread_join得到的终止状态是不同的,总结如下:
  1. 如果thread线程通过return返回,retval所指向的单元存放的是thread线程函数的返回值。
  2. 若果thread线程被别的线程调用pthread_cancel异常终止掉,retval指向单元里存放的是常数PTHREAD_CANCELED。

测试代码:

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

typedef struct {
    int a;
    int b;
} exit_t; 

void *tfn(void *arg)
{
    exit_t *ret;
    ret = (exit*)malloc(sizeof(exit_t));
    ret->a = 100;
    ret->b = 300;
    pthred_exit((void *) ret);
}
int main()
{
    pthread_t tid;
    exit_t *retval;
    pthread_create(&tid, NULL, tfn, NULL);
    
    /*调用pthread_join可以获取线程的退出转态*/ 
    pthread_join(tid, (void**)&retval);
    printf("a = %d, b = %d\n", retval->a, retval->b);
    
    return 0;
 } 

输出结果:

测试代码:

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

typedef struct {
    int ch;
    int var;
    char str[64];
}exit_t;

void *thrd_func(void *arg)
{
    exit_t *retval = (exit_t *)arg;
    retval->ch = 'm';
    retval->var = 200;
    strcpy(retval->str, "my thread\n");
    
    pthread_exit((void*) retval); 
}
int main()
{
    pthread_t tid;
    int ret;
    exit_t *retval = (exit_t *)malloc(sizeof(exit_t));
    
    printf("In main 1: thread id = %lu, pid = %u\n", pthread_self(), getpid());
    
    ret = pthread_create(&tid, NULL, thrd_func, (void*)retval);
    if(ret != 0) {
        fprintf(stderr, "pthread_create error: %s\n", strerror(ret));
        exit(1);
    }
    
    pthread_join(tid, (void**)&retval);
    printf("ch = %c, var = %d, str = %s\n", retval->ch, retval->var, retval->str);
    
    free(retval);
    pthread_exit((void *)1);
}

输出结果:

测试代码:

#include<stdio.h>
#include<string.h> 
#include<pthread.h>
#include<stdlib.h>
#include<string.h>
#include<unistd.h>
 
typedef struct {
    int ch;
    int var;
    char str[64];
}exit_t;
 
void *thrd_func(void *arg)
{
    exit_t *retvar = (exit_t *)malloc(sizeof(exit_t));
    retvar->ch = 'm';
    retvar->var = 200;
    strcpy(retvar->str, "my thread\n");
    
    pthread_exit((void*) retvar); 
}
int main()
{
    pthread_t tid;
    int ret;
    exit_t *retval;
    
    printf("In main 1: thread id = %lu, pid = %u\n", pthread_self(), getpid());
    
    ret = pthread_create(&tid, NULL, thrd_func, NULL);
    if(ret != 0) {
        fprintf(stderr, "pthread_create error: %s\n", strerror(ret));
        exit(1);
    }
    
    pthread_join(tid, (void**)&retval);
    printf("ch = %c, var = %d, str = %s\n", retval->ch, retval->var, retval->str);
    
    free(retval);
    pthread_exit((void *)1);
}

输出结果:

测试代码:

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

int var = 100;

void *tfn(void *arg)
{
    int i;
    i = (int) arg;
    
    sleep(i);
    if(i == 1) {
        var = 333;
        printf("var = %d\n", var);
        return (void*) var;
    } else if(i == 3) {
        var = 777;
        printf("I'm %dth pthread, pthread_id = %lu\n var = %d\n", i+1, pthread_self(), var);
        pthread_exit((void*)var);     
    } else {
        printf("I'm %dth pthread, pthread_id = %lu\n var = %d\n", i+1, pthread_self(), var);
        pthread_exit((void*)var);
    }
    return NULL;
}

int main()
{
    int i;
    pthread_t tid[5];
    int *ret[5];
    
    for(i = 0; i < 5; ++i) {
        pthread_create(&tid[i], NULL, tfn, (void*)i);

    }
    
    for(i = 0; i < 5; ++i) {
        pthread_join(tid[i], (void**)&ret[i]);
        printf("----------%d's ret = %d\n", (int)ret[i]);        
    }
    
    printf("I'm  main pthread tid = %lu\t var = %d\n", pthread_self(), var);
    sleep(i);
    return 0;    
}

输出结果:

猜你喜欢

转载自blog.csdn.net/isunbin/article/details/83272714
今日推荐