Linux之线程概念(pthread)

线程概念:(1)轻量级的进程,一个进程内部可以有多个线程,默认情况下一个进程只有一个线程。(2)线程是最小的执行单元,进程是最小的系统资源分配单位。(3)内核实现都是通过clone函数实现,线程也有自己的PCB。
查看pthread库版本命令:

~$ getconf GNU_LIBPTHREAD_VERSION
NPTL 2.23

1.创建线程创建线程在这里插入图片描述示例:cat pthread_create.c

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

void *thr(void *arg)
{
    printf("I am a thread!pid=%d,tid=%lu\n",getpid(),pthread_self());
    return NULL;
}

int main()
{
    pthread_t tid;
    pthread_create(&tid,NULL,thr,NULL);
    printf("I am a MAIN thread!pid=%d,tid=%lu\n",getpid(),pthread_self());
    pthread_exit(NULL);
    return 0;
}

pthread_self() :函数获得自身线程ID

编译:gcc file.name -lpthread

  • 在编译的时候也可以写脚本自动生成makefile文件–>make 编译
  • 在/home目录下.bashrc增加:alias echomake=‘cat ~/bin/makefile.template (根据自己文件名字)>> makefile’
  • $cat ~/bin//makefile.template
#create by ** 2021.2.21
SrcFiles=$(wildcard *.c)
TargetFiles=$(patsubst %.c,%,$(SrcFiles))
all:$(TargetFiles)
%:%.c
	gcc -o $@ $< -lpthread -g
clean:
	-rm -f $(TargetFiles)
  • $echomake -->生成makefile文件 (未实现??)

2.线程退出
pthread_exit(): 线程退出函数。线程退出注意事项:

  • 在线程中使用pthread_exit()
  • 在线程中使用return(主控线程return代表退出进程)
  • exit代表退出整个进程

3.线程回收
int pthread_join(pthread_t thread, void **retval);
线程回收函数–阻塞等待回收

  • thread 线程创建的时候传出的第一个参数
  • retval 代表传出线程的退出信息

实例:

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

void *thr(void *arg)
{
    printf("I am a thread,tid=%lu\n",pthread_self());
    sleep(5);
    printf("I am a thread,tid=%lu\n",pthread_self());
    pthread_exit((void*)101);
    //return (void*)100;
}

int main()
{
    pthread_t tid;
    pthread_create(&tid,NULL,thr,NULL);
    void *ret;
    pthread_join(tid,&ret); //线程回收
    printf("ret exit with %d\n",(int)ret);

    pthread_exit(NULL);
}

输出:
~$ gcc pthread_rtn.c -lpthread
~$ ./a.out
I am a thread,tid=140591370012416
I am a thread,tid=140591370012416
ret exit with 101

4.杀死线程
pthread_cancel()函数
原型:int pthread_cancel(pthread_t thread);

  • 需要输入tid;
  • 返回值:
    失败返回errno,成功返回0
    pthread_cancel杀死的线程,退出状态为PTHREAD_CANCELED
    #define PTHREAD_CANCELED ((void*)-1)
    示例:
#include<stdio.h>
#include<unistd.h>
#include<pthread.h>

void *thr(void *arg)
{
    while (1)
    {
        printf("I am a thread,keep running still be canceled!tid=%lu\n",pthread_self());
        sleep(1);
    }
    return NULL;    
}

int main()
{
    pthread_t tid;
    pthread_create(&tid,NULL,thr,NULL);

    sleep(5);
    pthread_cancel(tid);  //杀死线程

    void *ret;
    pthread_join(tid,&ret);  //线程回收
    printf("ret exit with %d\n",(int)ret);  //打印被杀死后的退出状态

    pthread_exit(NULL);
}

输出:
~$ gcc pthread_cancel.c -lpthread
~$ ./a.out
I am a thread,keep running still be canceled!tid=140291370272512
I am a thread,keep running still be canceled!tid=140291370272512
I am a thread,keep running still be canceled!tid=140291370272512
I am a thread,keep running still be canceled!tid=140291370272512
I am a thread,keep running still be canceled!tid=140291370272512
ret exit with -1

5.线程分离
在这里插入图片描述注意最后一句:如果一个线程调用pthread_detach()线程分离(自动回收机制),就不能再调用pthread_join()函数进行线程回收了。
示例:

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

void *thr(void *arg)
{
    printf("I am a thread,keep running still be canceled!tid=%lu\n",pthread_self());
    sleep(4);
    printf("I am a thread,keep running still be canceled!tid=%lu\n",pthread_self());
    return NULL;
}

int main()
{
    pthread_t tid;
    pthread_create(&tid,NULL,thr,NULL);

    pthread_detach(tid);  //线程分离

    int ret = 0;
    //void *tt;
    if((ret = pthread_join(tid,NULL)) > 0)  //判定分离之后是否还能回收
    {
        //printf("ret exit with %d\n",(int)tt);  //打印被杀死后退出状态,线程分离时应不存在
        printf("join err:%d,%s\n",ret,strerror(ret));
    }

    return 0;
}

输出:
~$ gcc pthread_detach.c -lpthread
~$ ./a.out
join err:22,Invalid argument

pthread_equal()函数:比较两个线程是否相等。
int pthread_equal(pthread_t t1, pthread_t t2);
有可能Linux未来线程ID pthread_t类型被修改为结构体实现。

6.创建多线程

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

void *thr(void *arg)
{
    int num = (int)arg;
    printf("I am %d thread,self=%lu\n",num,pthread_self());
    return (void *)(100+num);  
    //pthread_exit(NULL);
}

int main()
{
    pthread_t tid[5];
    int i;
    for(i=0; i<5; i++)
    {
        pthread_create(&tid[i],NULL,thr,(void *)i);
        sleep(1);
    }

    for(i=0; i<5; i++)
    {
        void *ret;
        pthread_join(tid[i],&ret); //有序回收线程
        printf("i == %d, ret == %d\n",i,(int)ret);
    }
    return 0;
}

输出:
~$ gcc npthreads.c -lpthread
~$ ./a.out
I am 0 thread,self=139840462472960
I am 1 thread,self=139840454080256
I am 2 thread,self=139840377059072
I am 3 thread,self=139840368666368
I am 4 thread,self=139840360273664
i == 0, ret == 100
i == 1, ret == 101
i == 2, ret == 102
i == 3, ret == 103
i == 4, ret == 104

7.线程属性
在这里插入图片描述

  • 线程控制
    int pthread_attr_init(pthreat_attr_t *attr); //初始化线程
    int pthread_attr_destroy(pthreat_attr_t *attr); //销毁线程
  • 设置线程分离状态/非分离状态方法:
    int pthread_attr_setdetachstate(pthread_attr_t *attr, int detachstate); //设置属性
    int pthread_attr_setdetachstate(pthread_attr_t *attr, int detachstate); //获得属性
    参数:attr 线程已初始化属性
    detachstate:设置属性,PTHREAD_CREATE_DETACHED 分离线程
    PTHREAD_CREATE_DETACHED 非分离线程
    示例:
#include<stdio.h>
#include<unistd.h>
#include<pthread.h>
#include<string.h>

void *thr(void *arg)
{
    printf("I am a thread\n");
}

int main()
{
    pthread_attr_t attr;
    pthread_attr_init(&attr); //初始化属性

    pthread_attr_setdetachstate(&attr,PTHREAD_CREATE_DETACHED); //设置属性分离状态
    pthread_t tid;
    pthread_create(&tid,&attr,thr,NULL);

    //线程回收
    int ret;
    if((ret = pthread_join(tid,NULL)) > 0)
    {
        printf("join err:%d,%s\n",ret,strerror(ret));
    }

    pthread_attr_destroy(&attr); //摧毁属性
    return 0;
}

在这里插入图片描述

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值