Linux---线程控制

操作系统没有直接给用户提供线程的系统调用函数 , 所有就要大佬将一套线程控制接口封装成了库函数共用户使用所以创建的线程是一个用户态的线程, 但是在内核中对应有一个轻量级进程实现程序的调度运行

线程创建

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

线程的创建是通过pthread_create()函数来完成的. 头文件是pthread.h 其中一共有四个参数

  1. thread
    是一个无符号整形的数据 , 它用来接收创建的线程的标识符
  2. attr
    用来设置线程的属性, 一般置位NULL , 表示使用默认属性
  3. void *(*start_routine) (void *)
    是一个函数指针, 传入的函数为创建线程的执行函数
  4. arg
    是一个参数 , 表示传入执行函数的参数
  5. 返回值: 创建线程成功则返回 0
//线程执行函数
void* fun(void* arg){
    while(1){
    printf("----------新线程---------  %s  \n",arg);	
    sleep(1);
}   
    return NULL;
}

int main(){
    //用来接收pthread_create的返回值, 判断线程是否创建成功
    int ret;
    //tid用来接收创建线程的ID
    pthread_t tid;
    //作为参数传入线程执行函数
    char* str="houxinggang";
    ret = pthread_create(&tid,NULL,fun,(void*)str);
    if(ret!=0){
	printf("创建线程失败!!\n");
	return -1;
    }
    while(1){
	printf("----------主线程---------      \n");
	sleep(1);
    }
    return 0;
}

执行代码后,可以看到主线程与新线程都在运行

在这里插入图片描述
进程ID与线程ID

线程终止

  1. return : 在主线程中return, 退出进程 在普通线程中return退出的是调用线程
  2. pthread_exit(void ** ratval) : 退出调用的线程(包含主线程)
    主线程退出,进程不会退出, 所有的线程推出,则进程退出 retval通常置空
  3. pthread_cancel (pthread_t tid) : 取消指定的现线程 (线程退出也会形成僵尸线程,多以线程也要等待)

以上书代码为例

void* fun(void* arg){
	int i=0;
    while(1){
    printf("----------新线程---------  %s  \n",arg);	
    i++;
    if(i==8)
    	pthread_exit(NULL);
    sleep(1);
}   
    return NULL;
}

int main(){
    //用来接收pthread_create的返回值, 判断线程是否创建成功
    int ret;
    //tid用来接收创建线程的ID
    pthread_t tid;
    //作为参数传入线程执行函数
    char* str="houxinggang";
    ret = pthread_create(&tid,NULL,fun,(void*)str);
    if(ret!=0){
	printf("创建线程失败!!\n");
	return -1;
    }
    while(1){
	printf("----------主线程---------      \n");
	sleep(1);
    }
    return 0;
}

创建线程在执行8秒之后退出
在这里插入图片描述

进程等待

线程需要被等待是有前提的 : 这个线程处于一个joinable属性, 一个线程被创建,有一个joinable属性, 这个属性的线程退出后不会自动回收资源,需要被等待

int pthread_join(pthread_t tid, void *retval); : tid:等待指定的线程ID retval用来接收退出返回值 此函实际上是一个阻塞函数, 当指定的线程没有退出时, 它将一直等待
*
注意 : 这里用于接受返回信息的retval是一个 void
类型的二级指针当我们按照如下的代码进行编写是会出现错误

//1.当给指针置空时
void** retval=NULL;
//2.当二级指针指向也指针时
void **retval;
pthread_join(tid,(char*)*retval);

在这里插入图片描述
如上图所示 char** 类型的 b 指针中存放的是一片 char类型空间的地址 , 而字符串的首地址将存放在 char 类型的的空间中 当我们给二级指针指向空时, 他里面存放的是非法的一块地址,当二级指针指向野地址时, 也是错误的 .

回去线程退出的返回值程序

void* str_statr(void* arg){
	char* buf="nuhao";
	sellp(5);
	return buf;
}

int main(){
	pthread_t pid;
	int ret=pthread_creat(&tid, NULL,str_statr,NULL);
	if(ret!=0){
		printf("线程创建失败!!\n");
		return -1;
	}
	void* retval;
	pthread_join(tid,&retval);
	printf("线程退出的原因:%s",(char*)retval);
	return 0;
}

进程分离

分离一个线程, 就是设置线程的属性, 将线程的joinable属性修改为detach属性, 处于这个属性的线程,退出之后将自动回收资源, 并且因为资源已经被自动释放,所以不能被等待, 否则报错;

pthread_detach(tid)

线程分离可以在任意线程任意时间分离, 包括分离自己;
分离一个线程的使用场景,用户根本不关心线程的处理结果

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值