线程控制

对线程的控制思路和进程相似,创建、等待、终止,只需要调用接口就行。但是在Linux下没有线程的概念,因为Linux的设计者认为,线程是一种轻量级的进程,毕竟创建线程只需要创建PCB。因此Linux中使用多线程必须使用第三方pthread库,线程库为用户提供接口。


线程的创建——pthread_create

参数:

tread是线程标识符的指针,类似进程pid

attr是线程属性,一般是nullptr

start_routine是线程执行的函数

arg是传递给线程函数的参数

返回值:

 


线程的终止

线程终止有三种方式:

1.线程函数执行return,就会结束进程

2.线程函数使用pthread_exit接口

3.一个线程中使用pthread_cancel接口终止另一个进程 


线程的等待——pthread_join

 

参数:

 thread是线程标识符

retval是标识符对应线程退出后的返回值,是一个输出型参数。因为线程函数的返回值是void*类型,所以参数类型必须是void**


进程控制的例子:

#include <iostream>
#include <pthread.h>
#include <string>
#include <unistd.h>
using namespace std;
//使用线程实现从a到b的累加
class Request
{
public:
    int _start;
    int _end;
    string _threadname;

    Request(int start, int end, string name)
    :_start(start)
    ,_end(end)
    ,_threadname(name)
    {}
};

class Response
{
public:
    int _val;
    int _exitcode;

    Response(int val, int exitcode)
    :_val(val)
    ,_exitcode(exitcode)
    {}
};

void* cal(void* arg)
{
    Request* rq = (Request*)arg;
    Response* rsp = new Response(0, 0);
    for(int i = rq->_start; i <= rq->_end; i++)
    {
        usleep(100000);
        rsp->_val += i;
        cout << rq->_threadname << " pid:" << getpid() << " operate" <<": ret += " << i << endl;
    }
    //线程间共用堆,把主线程的数据释放
    delete rq;
    return rsp;
}

int main()
{
    pthread_t tid;
    Request* rq = new Request(0,50,"mythread");
    //创建线程
    cout << "main thread pid:" << getpid() << " create thread" << endl;
    pthread_create(&tid, nullptr, cal, (void*)rq);
    void* ret;
    //等待线程,获取结果
    pthread_join(tid, &ret);
    Response* rsp = (Response*)ret;
    cout << rq->_threadname <<" cal ret = " << rsp->_val << " exitcode = " << rsp->_exitcode << endl; 
    delete rsp;
    return 0;
}

使用线程库,编译时要用-lpthread选项,声明使用的库
通过指令看到线程的PID相同,因为它们都是同一个进程的执行流资源,LWP是线程标识符,不同线程互不相同

 


线程ID

我们知道LInux系统没有线程概念,线程这个概念是由线程库来维护的,线程库调用了系统调用接口clone

 clone是创建进程的接口(fork的底层也使用了它),线程库对其封装,提供可以创建线程的接口。那么,线程库必然会对建立的所有线程进行管理,就像操作系统管理进程一样,创建对应的TCB等等。

线程库是一个动态库,进程运行时会加载到共享区。库中就有线程对应的数据结构,这些数据结构都被存储到一个数组中,数组中每个线程的数据结构的地址就是它的tid

相关推荐

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-07-14 03:22:02       67 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-07-14 03:22:02       72 阅读
  3. 在Django里面运行非项目文件

    2024-07-14 03:22:02       58 阅读
  4. Python语言-面向对象

    2024-07-14 03:22:02       69 阅读

热门阅读

  1. 数据库系统概论——数据库原理 总结1

    2024-07-14 03:22:02       22 阅读
  2. git 如何查看 commit 77062497

    2024-07-14 03:22:02       17 阅读
  3. 策略模式适用场景与具体实例解析

    2024-07-14 03:22:02       24 阅读
  4. Linux猜数字游戏

    2024-07-14 03:22:02       19 阅读
  5. Node.js_mongodb数据迁移

    2024-07-14 03:22:02       15 阅读