Liunx:线程控制

news/2025/2/1 9:11:38/

       

目录

创建线程:pthread_create();

线程等待:pthread_join();

线程退出:pthread_exit();

线程取消:pthread_cancel()


        说线程的时候说过,liunx没有选择单独定义线程的数据结构和适配算法,而是用轻量级进程来实现线程,有人将轻量级进程的系统调用进行了封装,在应用层实现了线程的相关功能,目前大部分的liunx平台都默认安装了第三方库,pthread.h。

        创建线程:pthread_create();

        man 一下该函数可以出现相关介绍:

        pthread_t *thread,输出型参数,一个进程可以创建多个线程,为了方便控制,该参数返回线程的id。这个是你在该函数之前需要定义的一个变量,pthread_t是一个长整型。 

     const pthread_attr_t *attr,用来设置创建线程时的属性,一般我们传递一个空指针,线程的属性使用系统默认的就可以。

        void *(*start_routine) (void *),函数指针,该函数返回值是void*,参数是void*。我们暂时把它叫做功能函数。

        void *arg,第三个参数传递了一个函数,这个参数将来会传给你的功能函数做参数。

        线程创建成功返回0,线程创建失败以返回值的形式返回错误码。

#include <iostream>
#include <pthread.h>
#include <unistd.h>using namespace std;void *Function(void *arg)
{while (true){cout << "new thread: " << getpid() << endl<< endl;sleep(2);}
}int main()
{pthread_t pid = 0;int err = pthread_create(&pid, nullptr, Function, nullptr);if (err == 0){cout << " create thread successfully!  " << endl;}while (true){cout << "main thread: " << getpid() << endl<< endl;sleep(1);}return 0;
}

        上面的代码演示了怎么创建一个线程,运行:


        ldd 可以查看你的程序链接了哪些库:

        查看进程也能看到只有一个mythread:

        从这也能说明,一个进程可以有多个线程,多个线程只是一个进程不同的执行流。

        但是查看线程的话,你可以明显看到这两个执行流:
 

        LWP,light weight process id,轻量级进程id。PID=LWP的线程就是主线程,也就是程序运行最先创建的PCB。

        当你任意的干掉一个线程,整个进程也会被干掉:

        

        我们kill 的不是主线程,而是进程中的一个新线程,进程中的任意一个线程崩溃都会导致整个进程的崩溃。专业点说,多线程较单线程,程序的健壮性降低。

        还要说一下创建线程成功后的第一个参数的值,用%p格式打印::

        tid不等于LWP,实际上是一个地址,至于为什么,稍后说。


线程等待:pthread_join();

        要等待某个线程,第一个参数就是创建该线程时的tid,第二个参数是用来取出你传入的功能函数的返回值。

        等待成功返回0,失败返回错误码。

        

void *Function(void *arg)
{int cnt=5;while (cnt--){cout << "new thread: " << getpid() << endl<< endl;sleep(1);}
}int main()
{pthread_t pid = 0;int err = pthread_create(&pid, nullptr, Function, nullptr);if (err == 0){cout << " create thread successfully!  " << endl;}int err_join=pthread_join(pid,nullptr);if(err_join==0){cout<<" new thread wait successfully! main thread exit....."<<endl;}return 0;
}

        运行:

        主线程在等待新线程5秒运行完成后才退出,默认是阻塞等待。如果主线程比新线程先退出,会造成类似于僵尸进程的情况,也就是新线程的创建的一些资源无法回收,造成内存泄露的问题。

        然后再说第二个参数。我们要知道一个函数的执行情况是根据函数的返回值,假如说我们没法在应用层接收功能函数的返回值,请问你如何知道函数的执行情况?或者你说可以通过错误码,但是一个进程只有一个错误码,可你有多个线程。其次我们无法捕捉到线程的异常,线程异常后整个进程都退出了,程序崩溃之后你只能知道有异常,至于哪个线程抛出的,没有办法捕捉。还有就是我们不主要用这个参数来查看线程的执行情况,他还有其他用途,后面说。在说为什么是一个二级指针。

        我们的功能函数返回一个void*值,这个值在应用层,我们就假设功能函数执行完成的返回值返回到了pthread_join()函数里,你想要拿到一个函数内部的void*类型的值,那你的输出型参数就应该是void** retval,在函数内部进行复制*retval(void*)=void* ;这样类型就匹配了。这样用:

线程退出:pthread_exit();

        线程退出你直接可以用return,也可以用这个,哪个线程调用这个函数,哪个线程就退出。

线程取消:pthread_cancel()

        在主线程里不等新线程运行结束就直接取消。

        


int main()
{pthread_t tid = 0;int err = pthread_create(&pid, nullptr, Function, nullptr);if (err == 0){cout << " create thread successfully!  " << endl;}sleep(1);//等待一秒确保线程创建成功pthread_cancel(tid);void* retval=nullptr;pthread_join(tid,&retval);cout<<" new thread wait successfully! "<<"exit:"<<(long long int)retval<<"main thread exit....."<<endl;   return 0;
}​


http://www.ppmy.cn/news/1324746.html

相关文章

打折:阿里云国外服务器价格购买优惠活动

阿里云国外服务器优惠活动「全球云服务器精选特惠」&#xff0c;国外服务器租用价格24元一个月起&#xff0c;免备案适合搭建网站&#xff0c;部署独立站等业务场景&#xff0c;阿里云服务器网aliyunfuwuqi.com分享阿里云国外服务器优惠活动&#xff1a; 全球云服务器精选特惠…

Spring MVC学习——解决请求参数中文乱码

解决请求参数中文乱码问题 1.POST请求方式解决乱码问题 在web.xml里面设置编码过滤器 <filter><filter-name>CharacterEncodingFilter</filter-name><filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class><…

AM5-DB低压备自投装置在河北冠益荣信科技公司洞庭变电站工程中的应用

摘 要&#xff1a;随着电力需求的不断增加&#xff0c;电力系统供电可靠性要求越来越高&#xff0c;许多供电系统已具备两回或多回供电线路。备用电源自动投入装置可以有效提高供电的可靠性&#xff0c;该类装置能够在工作电源因故障断开后&#xff0c;自动且迅速地将备用电源投…

EasyX图形化学习(三)

1.帧率&#xff1a; 即每秒钟界面刷新次数&#xff0c;下面以60帧为例&#xff1a; 1.数据类型 clock_t&#xff1a; 用来保存时间的数据类型。 2.clock( ) 函数&#xff1a; 用于返回程序运行的时间,无需参数。 3.例子&#xff1a; 先定义所需帧率&#xff1a; const …

C语言中宏定义中#和##使用详解

目录&#xff09; 一、简介二、使用详解2.1 # 是将后面的字符串加“”变成编译器眼中的字符串2.2 ## 是将两串字符联接成一串 三、其他相关链接1、C语言常用函数详细总结2、C语言中指针、数组作为作为函数参数使用总结3、C语言常见数据类型字节数和打印格式总结4、C语言、Makef…

FPGA 多路分频器实验

1 概述 在 FPGA 中&#xff0c;时钟分频是经常用到的。本节课讲解 2 分频、3 分频、4 分频和 8 分频的 Verilog 实现并且学习 generate 语法功能的应。 2 程序设计思路 1&#xff09;整数倍分频&#xff0c;为 2、4、8&#xff0c;这种 2^n 次方倍数倍数关系的…

Linux的权限(2)

目录 Linux的&#xff08;事物属性&#xff09;文件权限 文件权限值得表示方法 字符表示方法 8进制表示方法 文件访问权限得相关设置方法 chmod修改权限法1 chmod修改权限法2 文件的角色&#xff08;拥有者/所属者&#xff09;修改 chown拥有者 chgrp所属者 &…

rust获取本地ip地址的方法

大家好&#xff0c;我是get_local_info作者带剑书生&#xff0c;这里用一篇文章讲解get_local_info的使用。 get_local_info是什么&#xff1f; get_local_info是一个获取linux系统信息的rust三方库&#xff0c;并提供一些常用功能&#xff0c;目前版本0.2.4。详细介绍地址&a…