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;
}
相关推荐
Light602 小时前
领码方案|Linux 下 PLT → PDF 转换服务超级完整版:异步、权限、进度(一气呵成)
linux·spring boot·pdf·gpcl6/ghostpcl·s3/oss·权限与审计·异步与进度
YuTaoShao3 小时前
【LeetCode 每日一题】36. 有效的数独
linux·算法·leetcode
NiKo_W3 小时前
Linux 开发工具(1)
linux·运维·服务器
笑口常开xpr3 小时前
Linux动静态库开发基础:静态库与动态库的编译构建、链接使用及问题排查
linux·c语言·动态库·静态库
艾莉丝努力练剑4 小时前
【C++】类和对象(下):初始化列表、类型转换、Static、友元、内部类、匿名对象/有名对象、优化
linux·运维·c++·经验分享
风_峰4 小时前
PuTTY软件访问ZYNQ板卡的Linux系统
linux·服务器·嵌入式硬件·fpga开发
数智顾问4 小时前
从ENIAC到Linux:计算机技术与商业模式的协同演进——云原生重塑闭源主机,eBPF+WebAssembly 双引擎的“Linux 内核即服务”实践
linux
-SGlow-4 小时前
Linux相关概念和易错知识点(45)(网络层、网段划分)
linux·运维·服务器·网络
三体世界4 小时前
测试用例全解析:从入门到精通(1)
linux·c语言·c++·python·功能测试·测试用例·测试覆盖率