Linux基础部分的学习(8)-线程


前言

埋头苦干是第一,发白才知智叟呆。勤能补拙是良训,一分辛苦一分才。——华罗庚


一、线程是什么?和进程有什么区别?

进程:是指⼀个内存中运⾏的应⽤程序,每个进程都有⼀个独⽴的内存空间,⼀个应⽤程序可以同时运⾏多个进程;
进程也是程序的⼀次执⾏过程,是系统运⾏程序的基本单位;系统运⾏⼀个程序即是 ⼀个进程从创建、运⾏到消亡的过程。
(拷贝父进程的内存空间,拥有独立的内存空间,消耗资源大,效率低)

线程:线程是进程中的⼀个执⾏单元,负责当前进程中程序的执⾏,⼀个进程中⾄少有⼀个线程。
⼀个进程中是可以有多个线程的,这个应⽤程序也可以称之为多线程程序。(共享内存资源,崩溃后整个线程会一起崩溃)


多线程开发在 Linux 平台上已经有成熟的 pthread 库支持。其涉及的多线程开发的最基本概念主要包含三点:线程,互斥锁,条件。其中,
线程操作又分线程的创建,退出,等待 3 种。互斥锁则包括 4 种操作,分别是创建,销毁,加锁和解锁。条件操作有 5 种操作:创建,销毁,触发,广播和等待。
其他的一些线程扩展概念,如信号灯等

在这里插入图片描述

二、线程的创建

1.原型:

#include <pthread.h>

int pthread_create(pthread_t *restrict tidp,const pthread_attr_t *restrict attr,void *(*start_rtn)(void *),void *restrict arg);
tidp 指向的是新创建的线程ID
attr 定制不同属性线程
star_rtn 函数从该地址开始运行
成功返回0,失败返回错误编码;

int pthread_exit(void *rval_prt);		//线程的退出

int pthread_join(pthread_t thread,void **rval_ptr);		//线程的等待
成功返回0,失败返回错误的编号

int pthread_detach(pthread_t thread);		//线程脱离

pthread_t pthread_self(void);		//获取线程的ID

int pthread_equal(pthread_t tid1,pthread_t tid2);	//相等返回非0的数,否则返回0



2.代码分析

代码如下(示例):

#include <stdio.h>
#include <pthread.h>
#include <stdlib.h>
#include <unistd.h>
void *fun1(void *arg)
{
        static int pet = 10;
        printf("%ld thread is create \n",(unsigned long)pthread_self());
        printf("param is %d\n",*((int *)arg));
        pthread_exit((void *)&pet);
}

int main()
{
        int ret;
        int param = 100;
        int *repet = NULL;
        pthread_t t1;

        ret = pthread_create(&t1,NULL,fun1,(void *)&param);
        if(ret != 0){
                printf("thread create error\r\n");
                exit(-1);
        }

//      sleep(2);
        pthread_join(t1,(void **)&repet);
        printf("The pthread is %d\n",*repet);
        return 0;
}

三、互斥量加锁实验

1.互斥量的概述:

1.互斥:互斥锁,在同一时刻只能有一个执行流访问临界资源

2.互斥锁是一个阻塞接口,使用互斥锁来保证互斥属性,底层是互斥量,互斥量的本质是一个计数器,有0和1

3.计数器的值为:
	0:无法获取互斥锁,即临界资源无法访问,并阻塞在加锁操作
	1:可以获取互斥锁,互斥锁成功返回,并访问临界资源
#include <stdio.h>
#include <unistd.h>
#include <pthread.h>
#include <stdlib.h>

int g_data = 10;
pthread_mutex_t mutex;          //创建互斥锁

void *fun1(void *arg)
{
        pthread_mutex_lock(&mutex);
        for(int i=0;i < 4;i++){
        printf("The can is %d\n",*(int *)arg);
        printf("This is first thread1\n");
        printf("thread have create %ld\n",(unsigned long)pthread_self());
        sleep(1);
        }
        pthread_mutex_unlock(&mutex);
}

void *fun2(void *arg)
{
        sleep(1);
        (void)arg;
        pthread_mutex_lock(&mutex);
        for(int j=0;j<3;j++){
                printf("This is second thread2\n");
                printf("Thread have create %ld\n",(unsigned long)pthread_self());
        }
        pthread_mutex_unlock(&mutex);
}

int main()
{

//      int ret1,ret2;
        int param = 100;

        pthread_mutex_init(&mutex,NULL);
        pthread_t t1;
        pthread_t t2;

        if(pthread_create(&t1,NULL,fun1,(void *)&param) != 0){
                printf("thread create error\n");
                exit(-1);
        }

        if(pthread_create(&t2,NULL,fun2,NULL) != 0){
                printf("thread create error\n");
                exit(-1);
        }

        pthread_join(t1,NULL);
        pthread_join(t2,NULL);
        pthread_mutex_destroy(&mutex);
        return 0;
}

2.执行结果

在这里插入图片描述


四、互斥量加锁变成死锁

1.概述

一个执行流拿到锁资源,但没有释放就退出,会导致其它想要获取该互斥锁的执行流陷入阻塞等待,这种情况称为死锁。
当期执行流已经占用了一个互斥锁1,还申请新的互斥锁2,被阻塞,并且互斥锁1是无法解锁的(环型死锁)

五、线程条件控制实现线程的同步

1.概述:

条件变量是线程另一可用的同步机制。条件变量给多个线程提供了一个会合的场所。
条件变量与互斥量一起使用时,允许线程以无竞争的方式等待特定的条件发生。

条件本身是由互斥量保护的。线程在改变条件状态前必须首先锁住互斥量,
其他线程在获得互斥量之前不会察觉到这种改变,因为必须锁定互斥量以后才能计算条件。

2.代码实现:

#include <stdio.h>
#include <unistd.h>
#include <pthread.h>
#include <stdlib.h>
#include <stdlib.h>

int g_data = 0;
pthread_mutex_t mutex;          //创建互斥锁
pthread_cond_t cond;

void *fun1(void *arg)           //线程1的入口函数
{
        static int cnt = 0;
        while(1){
                pthread_cond_wait(&cond,&mutex);
                printf("The can is %d\n",*(int *)arg);
                printf("This is first thread1\n");
                printf("thread have create %ld\n",(unsigned long)pthread_self());
                printf("T1 timeout ==================================\n");
                printf("In fun1 data :%d\n",g_data);
                g_data = 0;
                if(cnt++ == 10){
                        printf("All work success\r\n");
                        exit(0);
                }
                sleep(1);

        }
}
void *fun2(void *arg)           //线程2的入口函:
{
        pthread_mutex_lock(&mutex);
        (void)arg;
        printf("This is second thread2\n");
        printf("Thread have create %ld\n",(unsigned long)pthread_self());

        while(1){
                sleep(1);

                g_data++;
                printf("In fun2 data :%d\n",g_data);

                if(g_data == 3){
                        pthread_cond_signal(&cond);
                        pthread_mutex_unlock(&mutex);
                }

        }
}

int main()
{
        int param = 100;

        pthread_mutex_init(&mutex,NULL);

        pthread_cond_init(&cond,NULL);

        pthread_t t1;
        pthread_t t2;

        if(pthread_create(&t1,NULL,fun1,(void *)&param) != 0){
                printf("thread create error\n");
                exit(-1);
        }

        if(pthread_create(&t2,NULL,fun2,NULL) != 0){
                printf("thread create error\n");
                exit(-1);
        }

        pthread_join(t1,NULL);
        pthread_join(t2,NULL);

        pthread_mutex_destroy(&mutex);
        pthread_cond_destroy(&cond);
        return 0;
}


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值