线程的应用

1、线程概念

由于进程的地址空间是私有的,因此在进程间上下文切换时,系统开销比较大,为了提高系统的性能,许多操作系统规范里引入了轻量级进程的概念,也被称为线程。

在同一个进程中创建的线程共享该进程的地址空间Linux里同样用task_struct来描述一个线程。线程和进程都参与统一的调度线程通过tid区分。

2、线程接口

1、pthread_create: 创建线程   

    #include <pthread.h>

    int pthread_create(pthread_t *thread, const pthread_attr_t *attr,

                       void *(*start_routine) (void *), void *arg);

   Compile and link with -pthread.  //编译时需要链接pthread库

例如:gcc pthread_create.c  -lpthtread

    参数:

        thread --- 线程ID

        attr   --- 线程属性,一般为NULL

        start_routine --- 线程执行函数

        arg    --- 向start_routine传参的参数

    返回值:

        成功:0

        失败:错误码

2、pthread_exit: 退出线程

    void pthread_exit(void *retval);

   参数: retval --- 返回值

3、pthread_cancel: 取消线程

4、pthread_join: 等待线程退出,并给线程回收资源

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

   参数:

        thread --- 线程ID

        retval --- 获取线程的返回值pthread_exit

5、pthread_detach: 分离线程,线程结束时自动回收资源

3、信号量

1、多线程共享同一个进程的地址空间

优点:线程间很容易进行通信, 通过全局变量实现数据共享和交换

缺点:多个线程同时访问共享对象时,需要引入同步和互斥机制

2、同步(synchronization)指的是多个任务(线程)按照约定的顺序相互配合完成一件事情

(1)信号量代表某一类资源,其值表示系统中该资源的数量

(2)信号量是一个受保护的变量,只能通过三种操作来访问

     * 初始化       sem_init

     * P操作(申请资源)    sem_wait

     * V操作(释放资源)    sem_post

信号量的值为非负整数

   二值信号量:0 (资源不可用)     1(资源可用)

   计数信号量: 0 ~ n

![](信号量.png)

1、sem_init: 初始化信号量

    #include <semaphore.h>

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

参数: sem --- 初始化的信号量

    pshared --- 0(线程间使用)

    value --- 信号量的值

    返回值:成功: 0

    失败: -1, 设置errno

2、sem_wait: p操作

        int sem_wait(sem_t *sem);

返回值:成功: 0

    失败: -1, 设置errno

3、sem_post:v操作

    int sem_post(sem_t *sem);

返回值:成功: 0

失败: -1, 设置errno

#include <stdio.h>

#include <pthread.h>

#include <unistd.h>

#include <string.h>

#include <stdlib.h>

#include <semaphore.h>

代码如下

char buf[100];

sem_t sem1; //生产者

sem_t sem2; //消费者

void *thread_func(void *arg)

{

    while (1)

    {

        //p操作:申请资源

        sem_wait(&sem2);

        printf("buf: %s\n", buf);

        //v操作:释放资源

        sem_post(&sem1);

    }

}

int main(int argc, char *argv[])

{

    pthread_t thread;

    if (0 > sem_init(&sem1, 0, 1))

    {

        perror("sem_init1");

        return -1;

    }

    if (0 > sem_init(&sem2, 0, 0))

    {

        perror("sem_init2");

        return -1;

    }

    int err = pthread_create(&thread, NULL, thread_func, NULL);

    if (err != 0)

    {

        fprintf(stderr, "pthread_create: %s\n", strerror(err));

        return -1;

    }

    while (1) //生产者

    {

        //p操作:申请资源

        sem_wait(&sem1);

        printf("Input: ");

        fgets(buf, sizeof(buf), stdin);

        //v操作:释放资源

        sem_post(&sem2);

    }

    return 0;

}

04、互斥锁

1、概念:

引入互斥(mutual exclusion)锁的目的是用来保证共享数据操作的完整性。

互斥锁主要用来保护==临界资源==

每个临界资源都由一个互斥锁来保护,任何时刻最多只能有一个线程能访问该资源

线程必须先获得互斥锁才能访问临界资源,访问完资源后释放该锁。如果无法获得锁,线程会阻塞直到获得锁为止

2、Ubuntu帮助文档安装ubuntu man手册不全,使用下面的方法安装:

   sudo apt-get install manpages-de  manpages-de-dev  manpages-dev glibc-doc manpages-posix-dev manpages-posix

3、互斥锁使用:

* 初始化   pthread_mutex_init

* 加锁:     pthread_mutex_lock

* 解锁:     pthread_mutex_unlock

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

এ᭄星辰

混口饭吃。。。。。

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值