Linux线程控制

线程创建

第一个参数是输出型参数,表示线程id;第二个参数是线程属性,NULL为默认属性;第三个参数是返回值void*,参数void*的函数指针;第四个是传递的参数。

使用该库需要编译时加上-pthread,使用c++封装的线程库在Linux中也要加。成功返回值0,出错返回错误码。

线程等待

阻塞方式等待

第二个参数是返回值,指针变量。

使用案例:

cpp 复制代码
#include<iostream>
using namespace std;
#include<unistd.h>
#include<pthread.h>
void* newthread(void * s)
{
    int n = 5;
    while(n--)
    {
        cout<<static_cast<char*>(s)<<endl;
        sleep(1);
    }
    return (void*)666;
}
string PrintHex(pthread_t& id)
{
    char buf[64];
    snprintf(buf, sizeof(buf), "%lx", id);
    return buf;
}
int main()
{
    pthread_t id;
    int n = pthread_create(&id, nullptr, newthread, (void *)"syx 666");
    if(n!=0)
    {
        cerr << "create thread error" << endl;
        return 1;
    }
    cout << PrintHex(id) << endl;
    void *code = nullptr;
    n = pthread_join(id, &code);
    if(n==0)
    {
        cout << "wait success!ret:" <<(uint64_t)code<< endl;
    }
    return 0;
}

线程只考虑正确返回,如果异常了,整个进程就崩溃了。当然返回可以不只是内置类型,还可以是自定义类型的数据。

批量线程创建:

cpp 复制代码
#include<iostream>
using namespace std;
#include<unistd.h>
#include<pthread.h>
#include<vector>
void* Threadrun(void* args)
{
    string name = static_cast<char*>(args);
    int cnt = 5;
    while (cnt--)
    {
        cout << name << " is run!" << endl;
        sleep(1);
    }
    return args;
}
int main()
{
    vector<pthread_t> tids;
    int num = 3;
    for (int i = 0; i < num; i++)
    {
        pthread_t id;
        char* name=new char[128];
        snprintf(name,128,"thread-%d",i+1);
        pthread_create(&id, nullptr, Threadrun, name);
        tids.emplace_back(id);
    }

    for (auto i : tids)
    {
        char *name;
        pthread_join(i, (void**)&name);
        cout << name << " over!" << endl;
    }
    return 0;
}

线程终止

main函数结束表示进程结束,此时新线程会被迫结束,因此要保证主线程最后退出。如果子线程使用exit退出,那么整个进程也退出了,exit是专门用终止进程的。可以用return终止。

对此,库里有专门终止线程的函数:

类似于return;我们还有另一种:

这个会发请求给子线程让它取消,返回值是有符号整数。使用案例:

cpp 复制代码
#include<iostream>
using namespace std;
#include<unistd.h>
#include<pthread.h>
#include<vector>
void* Threadrun(void* args)
{
    string name = static_cast<char*>(args);
    int cnt = 100;
    while (cnt--)
    {
        cout << name << " is run!" << endl;
        sleep(1);
    }
    return args;
}
int main()
{
    vector<pthread_t> tids;
    int num = 3;
    for (int i = 0; i < num; i++)
    {
        pthread_t id;
        char* name=new char[128];
        snprintf(name,128,"thread-%d",i+1);
        pthread_create(&id, nullptr, Threadrun, name);
        tids.emplace_back(id);
    }

    for (auto i : tids)
    {
        pthread_cancel(i);
        void *ret;
        pthread_join(i, &ret);
        cout << (long long)ret  << endl;
        // void *name;
        // pthread_join(i, (void**)&name);
        // cout << name << " over!" << endl;
    
    }
    return 0;
}

运行:

线程分离

如果想让线程自己退出回收资源,不要打扰别的线程,Linux提供了这个库函数:

这个函数就叫做线程分离;一个线程创建默认是joinable(必须join);一个线程被分离,线程的工作状态分离状态,不能被join,但依旧属于进程内部,但是不需要等待。新线程出异常还是会影响所有线程。

使用案例:

cpp 复制代码
#include<iostream>
using namespace std;
#include<unistd.h>
#include<pthread.h>
#include<vector>
void* Threadrun(void* args)
{
    pthread_detach(pthread_self());
    string name = static_cast<char *>(args);
    int cnt = 1;
    while (cnt--)
    {
        cout << name << " is run!" << endl;
        sleep(1);
    }
    return args;
}
int main()
{
    vector<pthread_t> tids;
    int num = 3;
    for (int i = 0; i < num; i++)
    {
        pthread_t id;
        char* name=new char[128];
        snprintf(name,128,"thread-%d",i+1);
        pthread_create(&id, nullptr, Threadrun, name);
        tids.emplace_back(id);
    }
    sleep(5);

    return 0;
}
相关推荐
夏日听雨眠3 小时前
LInux(逻辑地址与物理地址的区别,文件描述符,lseek函数)
linux·运维·网络
qq_542515415 小时前
Ubuntu 22.04.4 LTS安装ToDesk最新版打不开,无响应?旧版本4.7.2_277版本分享
linux·ubuntu·todesk
火车叼位5 小时前
替代 Tiny Win10 的 Linux 方案:Debian XFCE 精简桌面搭建
linux·运维
小麦嵌入式5 小时前
FPGA入门(四):时序逻辑计数器原理与 LED 闪烁实现
linux·驱动开发·stm32·嵌入式硬件·fpga开发·硬件工程·dsp开发
皮卡蛋炒饭.6 小时前
传输层协议UDP
linux·网络协议·udp
syagain_zsx7 小时前
Linux指令初识(实用篇)
linux·运维·服务器
王木风7 小时前
终端里的编程副驾:DeepSeek-TUI-项目深度拆解,实测与原理分析
linux·运维·人工智能·rust·node.js
槑槑紫7 小时前
windows系统装轻量版linux开发
linux·运维·服务器
齐潇宇8 小时前
k8s-Helm管理器
linux·运维·云原生·容器·kubernetes
Irene19918 小时前
(课堂笔记)Linux 基础命令:文件增删改、重命名、压缩等
linux