Linux线程操作函数

常用的Linux线程操作函数整理,便于以后查看和使用~

#include <pthread.h>

// 创建
int pthread_create(pthread_t *thread, const pthread_attr_t *attr,
                   void *(*start_routine) (void *), void *arg);
// 等待
int pthread_join(pthread_t thread, void **retval);
// 分离
int pthread_detach(pthread_t thread);
// 获取当前线程ID
pthread_t pthread_self(void);
// 只执行一次
int pthread_once(pthread_once_t t, void(*func)(void));
// 取消
int pthread_cancel(pthread_t thread);

int pthread_kill(pthread_t thread, int sig);
// 终止
void pthread_exit(void *rval_ptr);

pthread_create

函数原型

int pthread_create(pthread_t *thread, const pthread_attr_t *attr,
                   void *(*start_routine) (void *), void *arg)
// @argc1: 指向线程标识符发指针,type: pthread_t*
// @argc2: 设置线程属性(默认属性就NULL)
// @argc3: 线程运行函数的起始地址,type: (void*)(*)(void*)
// @argc4: 运行函数的参数,type: void*
    
// @return: 线程创建成功,函数返回0,不为0则说明线程失败

无参数函数

如果线程运行函数不需要传入参数,则@argc4为NULL。

#include <pthread.h>
#include <iostream>

using namespace std;

// 注意函数定义: void* (*)(void*)
void* test(void *ptr){
    cout << "hello world." << endl;
}

int main()
{
    pthread_t tid; // 声明线程id typedef unsigned
    pthread_create(&tid, NULL, test, NULL); // 创建线程
    pthread_join(tid, NULL);
}

带参数函数

如果线程运行函数需要传参,由于pthread_create只支持单个指针,只能传一个参数;如果要传多个参数,封装成结构体。

#include <pthread.h>
#include <string.h>
#include <iostream>

using namespace std;

struct Param{
    string name;
    int age;
};
// (void*)(*)(void*)
void* param_test(void* p){
    Param *param = (Param*)p;
    cout << "hello " << param->name << endl;
    cout << "age = " << param->age << endl;
}
int main()
{
    pthread_t tid;
    Param *ptr = new Param();
    ptr->name = "pthread";
    ptr->age = 20;
    pthread_create(&tid, NULL, param_test, ptr);
    pthread_join(tid, NULL);
}

类成员函数

比前面两种方式稍复杂,需要另外一个函数封装,该函数参数显式传入类实例指针,之后便与调用带参数函数的方法类似。

#include <pthread.h>
#include <string.h>
#include <iostream>

using namespace std;

class PthreadClass{
    public:
        void say_hello(){
            cout << "hello world" << endl;
        }
};

// 封装 传入类实例指针
void* class_test(void *p){
    PthreadClass *ptr = (PthreadClass*)p;
    // 实例调用
    ptr->say_hello();
}

int main()
{
    PthreadClass *ptr = new PthreadClass();
    pthread_t tid;
    pthread_create(&tid, NULL, class_test, ptr);
    pthread_join(tid, NULL);
}

pthread_join

用来等待一个线程的结束,线程间同步的操作。

函数原型

int pthread_join(pthread_t thread, void **retval);

@param1: 线程标识符,type: pthread_t

@param2: 用户定义的指针,用来存储线程的返回值,type: void**

#include <pthread.h>
#include <iostream>

using namespace std;

class PthreadClass{
    public:
        void say_hello(){
            cout << "hello world" << endl;
        }
};

int retval = -1;
void* class_test(void *p){
    PthreadClass *ptr = (PthreadClass*)p;
    ptr->say_hello();
    retval = 0;
    return (void*)&retval;
}

int main()
{
    PthreadClass *ptr = new PthreadClass();
    pthread_t tid;
    pthread_create(&tid, NULL, class_test, ptr);
    /**
     * 等待结束
     * 注意,如果不加pthread_join,那么有可能新线程还没等创建出来就已经结束程序
     */
    void *retval;
    pthread_join(tid, &retval);
    cout << *(int*)retval << endl;
}

pthread_detach

创建一个线程默认是joinable的,如果一个线程结束运行但没有被pthread_join,则它的状态类似于进程中的僵尸进程,还有一部分资源没有被回收(退出状态码),所以创建线程者应该pthread_join来等待线程的结束,并可得到线程的退出代码,回收其资源(类似于wait, waitpid)

调用pthread_join后,如果该线程没有运行结束,调用者会阻塞,在有些情况下我们并不希望如此(适用于有先后执行顺序的逻辑代码),例如web服务器处理多个链接,不能因为阻塞在等待线程运行结束,这样无法处理其他连接请求。此时可以调用pthread_detach来脱离阻塞,这时候子线程状态就变成detached,运行结束后会自动释放资源。

函数原型

int pthread_detach(pthread_t tid);
// @tid: 线程标识符,type: pthread_t
#include <pthread.h>
#include <unistd.h>
#include <iostream>

using namespace std;

void* test(void *p){
    sleep(30);
}

int main()
{
    pthread_t tid;
    pthread_create(&tid, NULL, test, NULL);
    //pthread_detach(tid, NULL);  //用join会阻塞等待test执行完毕才会打印下面的数字
    pthread_detach(tid);
    for(int i = 0; i < 10; i ++){
        sleep(1);
        cout << "sleep " << i << " second." << endl;
    }
}

pthread_self

作用是获取当前线程ID。

函数原型

pthread_t pthread_self(void);

无参数

#include <pthread.h>
#include <unistd.h>
#include <iostream>

using namespace std;

void* test(void *p){
    cout << 'child thread: ' << pthread_self() << endl;
}

int main()
{
    pthread_t tid;
    pthread_create(&tid, NULL, test, NULL);
    pthread_detach(tid);
    cout << 'main thread: ' << pthread_self() << endl;
}

pthread_once

在多线程环境中只执行依次,将多线程环境中只需要执行一次的操作交给pthread_once执行。

函数原型

int pthread_once(pthread_once_t tid, void(*func)(void));
// @param1: 相当于标识符, type: pthread_once_t
// @param2: 无参数函数指针,type: void(*func)(void)

pthread_cancel

发送一个cancel信号给指定线程,只有一个参数线程标识符,类型为pthread_t

函数原型

int pthread_cancel(pthread_t thread);
// @param: 线程ID,type: pthread_t

pthread_kill

向某个线程传递一个信号,需要在创建的线程中使用signal(SIGKILL, sig_handler)函数处理信号,如果你给一个线程发送了SIGQUIT,但线程却没有实现signal函数,则整个进程退出。

函数原型

int pthread_kill(pthread_t thread, int sig);
// @param1: 线程标识符,type: pthread_t
// @param2: Linux定义的信号,type: int

pthread_exit

线程通过调用pthread_exit函数终止执行,就如同进程在结束时调用exit函数一样。这个函数的作用是,终止调用它的线程并返回一个指向某个对象的指针。

函数原型

void pthread_exit(void *rval_ptr);

// @param: 返回的指针,type: void*
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值