【Linux-day11-线程的创建与同步】

这篇具有很好参考价值的文章主要介绍了【Linux-day11-线程的创建与同步】。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

Linux 线程的创建与同步

线程的概念

线程是进程内部的一条执行序列或执行路径,一个进程可以包含多条线程。 【Linux-day11-线程的创建与同步】,Linux学习,linux

进程与线程的区别
  • 进程是资源分配的最小单位,线程是 CPU 调度的最小单位
  • 进程有自己的独立地址空间,线程共享进程中的地址空间
  • 进程的创建消耗资源大,线程的创建相对较小
  • 进程的切换开销大,线程的切换开销相对较小
线程的实现方式

在操作系统中,线程的实现有以下三种方式:

  • 内核级线程
  • 用户级线程
  • 组合级线程

【Linux-day11-线程的创建与同步】,Linux学习,linux

Linux 中线程的实现

Linux 实现线程的机制非常独特。从内核的角度来说,它并没有线程这个概念。Linux 把
所有的线程都当做进程来实现。内核并没有准备特别的调度算法或是定义特别的数据结构来
表征线程。相反,线程仅仅被视为一个与其他进程共享某些资源的进程。每个线程都拥有唯
一隶属于自己的 task_struct,所以在内核中,它看起来就像是一个普通的进程(只是线程和
其他一些进程共享某些资源,如地址空间)。

线程库中的接口介绍
pthread_create()用于创建线程

int pthread_create(pthread_t *thread, **const ** pthread_attr_t *attr, void *(*start_routine) (void *), void *arg);

成功返回 0, 失败返回错误码

thread: 接收创建的线程的 ID

attr: 指定线程的属性

start_routine: 指定线程函数

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

pthread_exit()退出线程

int pthread_exit(void *retval);

pthread_exit()退出线程

retval:指定退出信息

pthread_join()等待 thread 指定的线程退出,线程未退出时,该方法阻塞

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

retval:接收 thread 线程退出时,指定的退出信息

测试代码1
#include<unistd.h>
#include<stdio.h>
#include<stdlib.h>
#include<pthread.h>

void* fun(void* arg)
{
    int* p = (int*)arg;
    int val = *p;
        printf("%d\n",val);
    return NULL;
}

int main()
{
    pthread_t id[5];
    int i=0;
    for(;i<5;i++)
    {
        pthread_create(&id[i],NULL,fun,(void*)&i);
    }
    for(i=0;i<5;i++)
    {
        pthread_join(id[i],NULL);
    }
    exit(0);
}

预估:会出现0 1 2 3 4按一定顺序

结果如图:

【Linux-day11-线程的创建与同步】,Linux学习,linux

我们发现结果和预想的不一样,这是因为线程是并发运行的,主线程main()和5个副线程都在同时运行,fun是通过指针解引用,主线程会随时改变i的值 ; pthread_create(&id[i],NULL,fun,(void*)&i);只是向内核申请,不一定顺序批准。

测试代码2
#include<unistd.h>
#include<stdio.h>
#include<stdlib.h>
#include<pthread.h>
int val = 0;
void* fun(void* arg)
{
    for(int i=0;i<1000;i++)
    {
        printf("%d\n",++val);
    }
    return NULL;
}
int main()
{
    pthread_t id[5];
    int i=0;
    for(;i<5;i++)
    {
        pthread_create(&id[i],NULL,fun,(void*)&i);
    }
    for(i=0;i<5;i++)
    {
        pthread_join(id[i],NULL);
    }
    exit(0);
}

预期: 输出5000

结果如图:

【Linux-day11-线程的创建与同步】,Linux学习,linux

这是因为线程是并发执行的,上一个线程对val进行++完,还没有写回内存,下个进程读取了之前的值对其++;

线程同步

1. 信号量

函数介绍

int sem_init(sem_t * sem, int pshared,unsigned int value)

sem: 指向的信号量对象

pshared: 0表示此信号为当前进程局部的,否则为多个进程间共享

value: 设置信号的值

int sem_wait(sem_t * sem)

进行p操作,信号值减1

sem: 指向的信号量对象

int sem_post(sem_t * sem)

进行v操作,信号值加1

sem: 指向的信号量对象

int sem_destory(sem_t * sem)

j清理该信号拥有的所有资源,成功返回0

sem: 指向的信号量对象

下面使用该方法对测试代码2修改

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

int val = 0;
sem_t sig;
void* fun(void* arg)
{
    for(int i=0;i<1000;i++)
    {
        sem_wait(&sig);
        printf("%d\n",++val);
        sem_post(&sig);
    }
    return NULL;
}
int main()
{
    pthread_t id[5];
    sem_init(&sig,0,1);
    int i=0;
    for(;i<5;i++)
    {
        pthread_create(&id[i],NULL,fun,(void*)&i);
    }
    for(i=0;i<5;i++)
    {
        pthread_join(id[i],NULL);
    }
    sem_destroy(&sig);
    exit(0);
}

结果如图:

【Linux-day11-线程的创建与同步】,Linux学习,linux

2.互斥锁

接口介绍:

1.int pthread_mutex_init(pthread_mutex_t* mutex,const pthread_mutexattr_t * mutexattr);

初始化锁
mutex: 互斥变量的指针
mutexattr: 设置互斥锁的属性

2.int pthread_mutex_lock(pthread_mutex_t* mutex);

上锁(加锁)

3.int pthread_mutex_unlock(pthread_mutex_t* mutex);

解锁

4.int pthread_mutex_destroy(pthread_mutex_t* mutex);

销毁锁

使用此方法修改测试代码2

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


int val = 0;
pthread_mutex_t mutex;
void* fun(void* arg)
{
    for(int i=0;i<1000;i++)
    {
        pthread_mutex_lock(&mutex);
        printf("%d\n",++val);
        pthread_mutex_unlock(&mutex);
    }
    return NULL;
}

int main()
{
    pthread_t id[5];
    pthread_mutex_init(&mutex,NULL);
    int i=0;
    for(;i<5;i++)
    {
        pthread_create(&id[i],NULL,fun,(void*)&i);
    }
    for(i=0;i<5;i++)
    {
        pthread_join(id[i],NULL);
    }
    pthread_mutex_destroy(&mutex);
    exit(0);

}

结果如图:

【Linux-day11-线程的创建与同步】,Linux学习,linux文章来源地址https://www.toymoban.com/news/detail-709460.html

到了这里,关于【Linux-day11-线程的创建与同步】的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Linux 线程和线程同步

     【操作系统】2.进程和线程 - imXuan - 博客园 (cnblogs.com) 线程:light weight process(LWP)轻量级的进程,在 Linux 中本质上仍然是一个进程 进程:有独立的地址空间,独立PCB,可以当作只有一个线程的进程。进程是计算机 资源分配的最小单位 线程:有独立的PCB,共享物理地址空间

    2024年02月05日
    浏览(41)
  • 『Linux』第九讲:Linux多线程详解(三)_ 线程互斥 | 线程同步

    「前言」文章是关于Linux多线程方面的知识,上一篇是 Linux多线程详解(二),今天这篇是 Linux多线程详解(三),内容大致是线程互斥与线程同步,讲解下面开始! 「归属专栏」Linux系统编程 「主页链接」个人主页 「笔者」枫叶先生(fy) 「枫叶先生有点文青病」「每篇一句

    2024年02月02日
    浏览(70)
  • 【Linux】Linux线程互斥与同步

    临界资源:多线程执行流共享的资源就叫做临界资源 临界区:每个线程内部,访问临界资源的代码,就叫做临界区 互斥:任何时刻,互斥保证有且只有一个执行流进入临界区,访问临界资源,通常对临界资源起保护作用 原子性:不会被任何调度机制打断的操作,该操作只有

    2024年02月04日
    浏览(39)
  • Linux——线程3|线程互斥和同步

    我们上一篇提到过,多个线程执行下面代码可能会出错,具体原因可查看上一篇Linux博客。 为避免这种错误的出现,我们可采用加锁保护。 PTHREAD_MUTEX_INITIALIZER 用pthread_mutex_t定义一把锁。ptherad_mutex_init是对锁进行初始化的函数。如果这把锁是全局的并且是静态定义的,我们可

    2024年02月05日
    浏览(44)
  • Linux和windows进程同步与线程同步那些事儿(五):Linux下进程同步

    Linux和windows进程同步与线程同步那些事儿(一) Linux和windows进程同步与线程同步那些事儿(二): windows线程同步详解示例 Linux和windows进程同步与线程同步那些事儿(三): Linux线程同步详解示例 Linux和windows进程同步与线程同步那些事儿(四):windows 下进程同步 Linux和wi

    2024年02月02日
    浏览(39)
  • Linux--线程-条件控制实现线程的同步

    1.条件变量 条件变量是线程另一可用的同步机制。条件变量给多个线程提供了一个会合的场所。条件变量与互斥量一起使用时,允许线程以无竞争的方式等待特定的条件发生。 条件本身是由互斥量保护的。线程在改变条件状态前必须首先锁住互斥量,其他线程在获得互斥量之

    2024年02月05日
    浏览(39)
  • 【Linux】线程同步和互斥

    1.临界资源:多线程执行流共享的资源,且一次只能允许一个执行流访问的资源就叫做临界资源。(多线程、多进程打印数据) 2.临界区:每个线程内部,访问临界资源的代码,就叫做临界区。 3.互斥:任何时刻,互斥保证有且只有一个执行流进入临界区,访问临界资源,通常对

    2024年02月08日
    浏览(42)
  • Linux线程同步实例

    生产者消费者模型是一种常用的并发设计模式,它可以解决生产者和消费者之间的速度不匹配、解耦、异步等问题。生产者消费者模型的应用场景有很多,例如Excutor任务执行框架、消息中间件activeMQ、任务的处理时间比较长的情况下等。 生产者消费者模型的基本结构如下 :

    2024年02月07日
    浏览(36)
  • 【Linux】线程同步

    初始化条件变量-pthread_cond_init 初始化条件变量的函数叫做 pthread_cond_init 参数说明 cond:需要初始化的条件变量 attr:初始化条件变量的属性,一般设置为NULL 返回值说明 初始化成功返回0,失败返回错误码 注意:调用 pthread_cond_init 函数初始化条件变量叫做动态分配,我们还可以用静

    2024年02月07日
    浏览(30)
  • Linux->线程同步

    前言: 1 线程同步引入 2 条件变量 2.1 线程饥饿 2.2 条件变量接口 2.3 添加条件变量 3 生产者和消费者模型         本篇主要讲解了关于线程同步的相关知识,还有生产者和消费者模型的认识和使用。         在讲解线程同步之前,我们先来看一下当一个程序之中只有线程互

    2024年02月11日
    浏览(28)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包