Linux 线程相关接口使用示例

3 篇文章 0 订阅
2 篇文章 0 订阅
#include <pthread.h>
#include <QDebug>
void *working(void *arg)
{
    qDebug()<<"我是子线程1,线程id:"<<pthread_self()<<"\n";

    for(int i=0;i<9;i++)
    {
        qDebug()<<"子线程1:"<<i<<"\n";
    }

    return nullptr;
}

void *working2(void *arg)
{
    qDebug()<<"我是子线程2,线程id:"<<pthread_self()<<"\n";

    for(int i=0;i<22;i++)
    {
        qDebug()<<"子线程2:"<<i<<"\n";
    }

    return nullptr;
}

int main()
{
    //返回当前线程id
    pthread_t id_parent = pthread_self();
    qDebug()<<"主线程id:"<<id_parent<<"\n";
    //创建子线程,第二个参数是线程的属性
    pthread_t tid_children;
    pthread_create(&tid_children,NULL,working,NULL);
    qDebug()<<"子线程1id:"<<tid_children<<"\n";
    //
    //创建子线程
    pthread_t tid_children2;
    pthread_create(&tid_children2,NULL,working2,NULL);
    qDebug()<<"子线程2id:"<<tid_children2<<"\n";
    //主线程执行代码
    qDebug()<<"我是主线程,id:"<<pthread_self()<<"\n";
    for(int i=10;i<20;i++)
    {
        qDebug()<<"主线程:"<<i<<"\n";
    }

    //线程退出不会影像其他线程,主线程一样,参数是退出时携带的数据,由该线程的主线程接收
    pthread_exit(NULL);

    //当一个线程处于join状态,无论线程使用phtread_exit还是return返回结果,终止线程所占用的资源不会随着线程的结束而归还系统,而是仍为线程所在进程持有
    //因此在默认情况下,一个线程被创建后,必须使用pthread_join对创建线程进行资源回收
    return 0;
}

(1)pthread_exit相当于函数的return,退出线程对其他线程没有影响,也可以用来传值给主线程(这里把创建其他线程的线程称为主线程);
(2)线程必须用pthread_join或者pthread_detach来回收线程本身所占用的资源;

#include <pthread.h>
#include <QDebug>
void *working(void *arg)
{
    int *p=(int *)arg;
    *p =3;
    pthread_exit(p);
    return nullptr;
}

int main()
{
    int p=2;
    pthread_t children_thread;
    qDebug()<<"p:"<<p<<"\n";
    int ret = pthread_create(&children_thread,NULL,working,&p);
    if(ret ==0)
    {
        qDebug()<<"create success\n";
    }
    else
    {
        qDebug()<<"create fail\n";
    }
    void *ptr=NULL;
    //修改ptr指针指向pthread_exit参数指向的内存,ptr指针与pthread_exit参数指向同一块内存
    //所以传入ptr指针地址,用于修改
    pthread_join(children_thread,&ptr);
    int *res = (int *)ptr;
    qDebug()<<"p:"<<p<<"\n";
    qDebug()<<"res:"<<*res<<"\n";
    return 0;
}

(1)线程的返回值用pthread_exit,接收参数的线程用pthread_join;
(2)可以用主线程的内存,使用pthread_create来传参;

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

using namespace std;
#define MAX 10
int number=0;
pthread_mutex_t m_mutex= PTHREAD_MUTEX_INITIALIZER;

void *funA(void *arg)
{
    for(int i=0;i<MAX;i++)
    {
        //pthread_mutex_lock(&m_mutex);
        int ret = pthread_mutex_trylock(&m_mutex);
        if(ret!=0)
        {
            qDebug()<<"mutex is not avaliable";
        }
        else
        {
            if(i==5)
            {
                break;
            }
            qDebug()<<"funA-before:"<<number;
            int cur=number;
            cur++;
            number=cur;
            qDebug()<<"funA-after:"<<number;
            pthread_mutex_unlock(&m_mutex);
        }
        //只有锁里面的是正常结果,下面这条qDebug在锁外面,有可能执行到这条语句之前时间片被funB抢走
        //所以本来应该显示正常结果,会显示funB运行完后的结果
        //qDebug()<<"funA:"<<number;
    }
    return NULL;
}

void *funB(void *arg)
{
    for(int i=0;i<MAX;i++)
    {
        //pthread_mutex_lock(&m_mutex);
        int ret = pthread_mutex_trylock(&m_mutex);
        if(ret!=0)
        {
            qDebug()<<"mutex is not avaliable";
        }
        else
        {
            qDebug()<<"funB-before:"<<number;
            int cur=number;
            cur++;
            number=cur;
            qDebug()<<"funB-after:"<<number;
            pthread_mutex_unlock(&m_mutex);
        }
        //qDebug()<<"funB:"<<number;
    }
    return NULL;
}

int main(int argc,char **argv)
{
    //pthread_mutex_init(&m_mutex,NULL);

    pthread_t p1,p2;
    pthread_create(&p1,NULL,funA,NULL);
    pthread_create(&p2,NULL,funB,NULL);

    pthread_join(p1,NULL);
    pthread_join(p2,NULL);
    qDebug()<<"here";

    pthread_mutex_destroy(&m_mutex);
    return 0;
}

(1)使用pthread_mutex_lock时会出现死锁的问题,如果funA突然break,锁没有解开,funB会一直阻塞,pthread_mutex_lock等不到锁会一直阻塞,所以使用pthread_mutex_trylock代替,如果拿不到锁会直接返回非0的值;
(2)还可以使用pthread_mutex_timedlock定时解锁函数;
(3)在c++线程函数中有std::lock_guard和std::unique_lock函数,两者都可以预防以上死锁情况,std::lock_guard出了定义域就可以解锁,里面的设计非常巧妙,该类在构造函数中加锁,在析构函数中解锁。unique_lock相比于lock_guard提供了更多接口,但性能不如lock_guard;
(4)c++线程库相比于Linux线程库会少很多功能,因此还是建议使用linux线程函数;

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值