Linux系统编程阶段:多线程编程相关知识和函数介绍。

一、多线程

进程:程序在系统中执行和资源分配的基本单位,程序加载到内存中运行。

线程:

轻量级的进程

进程内的基本的调度单位

共享进程的内存空间,其他的资源

线程的优点:

线程占用的系统的资源比进程要少的多;

线程的创建要比进程的创建要简单的多;

线程的创建的速度比进程的创建的速度要快很多;

线程的切换的速度要比进程的切换的速度快的多

缺点:线程一死俱死

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

函数的接口:

线程也有一个关键字   ---------pthread

pthread_create():创建一个线程

函数的头文件:pthread.h

函数的原型:

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

函数的参数:

        pthread_t *thread:线程的id号,类似于进程的进程号

        const pthread_attr_t *attr:线程的属性(分离属性、绑定属性), 一般填写NULL即可

        void *(*start_routine)(void *):线程要做的事情,线程的实现函数

                eg:void *myfunc(void * arg)

        void *arg:传给线程的实现函数的参数 ,一般为0

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

注意:

多线程的调度的次序跟进程的调度次序类似,无法确定谁先执行,谁后执行。

在编译用到线程相关的函数的时候,要在编译命令的后边加上 库的引用   -lpthread   

 eg:gcc app.c -o app -lpthread

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

pthread_self():获取自己的线程的pid号,格式控制符%ld

        头文件:同上

        函数的原型:phread_t pthread_self(void)

        函数的参数:无

        函数的返回值:成功返回 线程的pid号

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

进程的退出有专门的函数

pthread_exit():线程的正常退出

        头文件:同上

        函数的原型: void pthread_exit(void *retval)

        函数的参数:线程退出的状态,一般写NULL

        函数的返回值:无

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

pthread_join():等待一个线程结束,类似于进程里wait/waitpid

        头文件:同上

        函数的原型:int pthread_join(pthread_t thread,void**retval)

        函数的参数:

                pthread_t thread:要等待的线程号

                void**retval:线程返回的状态值,一般写NULL

        函数的返回值:成功返回 0    失败返回 error

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

pthread_cancel():取消一个线程的执行,无论被取消的线程的状态如何都强制取消,取消有一定的时间,在要取消的线程里面加个sleep

        头文件:同上

        函数的原型:int pthread_cancel(pthread_t thread);

        函数的参数:pthread_t thread:线程号

        函数的返回值:成功返回  0    失败返回  非零值

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

线程的钩子函数,用来清理线程的

pthread_cleanup_push();pthread_cleanup_pop(): 退出清零函数

pthread_cleanup_push()带有一个"{",而pthread_cleanup_pop()带有一个"}",因此这两个函数必须成对出现,且必须位于程序的同一级别的代码段中才能通过编译。一般中间可以有其他语句出现,只要不影响“{}”就行。

        头文件:同上

        函数原型:void pthread_cleanup_push(void (*routine)(void*), void *arg);        

                         void pthread_cleanup_pop(int execute);

        参数:

                void (*routine)(void*):清理的回调函数

                        eg:void mufunc(void *arg);

                void *arg:传递给清理函数的参数,一般为NULL

                execute:显示回调函数是否使能

                        0:表示不调用

                        1:非零,表示调用

二、线程的同步与互斥

如果使用同步和互斥一定所有的线程都要遵循这个操作,否则就没有意义。

1.作用:实现对资源的保护,以及独占

2.手段:互斥锁、条件变量、信号灯

3.互斥锁:本质就是一个结构体变量,作用就是保护临界资源,操作有两个,加锁和解锁

4.互斥锁的流程

        初始化:pthread_mutex_init

        上锁:pthread_mutex_lock

        解锁:pthread_mutex_unlock

        销毁锁:pthread_mutex_destroy

        注意:使用锁的时候 必须要安装相关的库文件

                apt-get install manpages-posix-dev

5.互斥锁的函数

int pthread_mutex_init():初始化一个互斥锁(动态创建)

        头文件:pthread.h

        函数原型:

int pthread_mutex_init (pthread_mutex_t *mutex,const pthread_mutexattr_t *__mutexattr)

        参数:

        pthread_mutex_t *mutex:互斥锁的结构体的指针

        const pthread_mutexattr_t *__mutexattr:锁的类型

        NULL:创建快速互斥锁

        返回值:成功,0   失败,error

        静态创建:

pthread_mutex_t lock =PTHREAD_MUTEX_INITIALIZER;

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

int pthread_mutex_lock();

int pthread_mutex_trylock():互斥锁的加锁

        头文件:pthread.h

        函数原型:

        int pthread_mutex_lock(pthread_mutex_t *mutex);

        阻塞的加锁,当申请到锁,则返回,申请不到则阻塞

        int pthread_mutex_trylock(pthread_mutex_t *mutex);

        非阻塞的申请锁,当申请到锁的时候马上返回,申请不到也马上返回,成功申请到锁   返回0,失败  返回非零

        参数:pthread_mutex_t *mutex:互斥锁的结构体的指针

+++++++++++++++++++++++++++++++++++++++++++++++++++++++

pthread_mutex_unlock():互斥锁的解锁

        头文件:pthread.h

        函数的原型:int pthread_mutex_unlock(pthread_mutex_t *mutex);

+++++++++++++++++++++++++++++++++++++++++++++++++++++++

pthread_mutex_destroy():销毁锁

        头文件:pthread.h

        函数的原型:

        int pthread_mutex_destroy(pthread_mutex_t *mutex);

6.条件变量

使用方法和锁差不多

+++++++++++++++++++++++++++++++++++++++++++++++++++++++

pthread_cond_init():(动态创建)条件变量的结构体的初始化

        函数的原型:

int pthread_cond_init(pthread_cond_t *restrict cond,const pthread_condattr_t *restrict attr);

        函数的参数:

                pthread_cond_t *restrict cond:条件变量结构体

                const pthread_condattr_t *restrict attr:固定填NULL

静态创建

pthread_cond_t cond = PTHREAD_COND_INITIALIZER;

+++++++++++++++++++++++++++++++++++++++++++++++++++++++

pthread_cond_wait():满足不了条件则阻塞线程

        函数的原型:

int pthread_cond_wait(pthread_cond_t *restrict cond,pthread_mutex_t *restrict mutex);

        函数的参数:

                pthread_cond_t *restrict cond:条件变量的结构体指针

                pthread_mutex_t *restrict mutex:互斥锁的结构体的指针

+++++++++++++++++++++++++++++++++++++++++++++++++++++++

pthread_cond_signal():解除线程的阻塞

        函数的原型:int pthread_cond_signal(pthread_cond_t *cond);

        函数的参数:pthread_cond_t *cond:条件变量的结构体

+++++++++++++++++++++++++++++++++++++++++++++++++++++++

pthread_cond_destroy():销毁条件变量

        函数原型:int pthread_cond_destroy(pthread_cond_t *cond);

7.信号灯

信号量本质上就是一个能进行加或者是减操作的一个数,信号灯几乎和进程中信号量一样(但还是不同),当这个数减到0,就表示资源没有了,陷入阻塞。

+++++++++++++++++++++++++++++++++++++++++++++++++++++++

sem_init():信号灯的创建

        头文件:semaphore.h
        原型: int sem_init(sem_t *sem, int pshared, unsigned int value);

        参数:

                sem_t *sem:信号灯的核心结构体

                int pshared:固定填0

                unsigned int value:信号灯的初值

        返回值:成功返回 0      失败返回  非零

+++++++++++++++++++++++++++++++++++++++++++++++++++++++

sem_wait():p操作,消耗一个信号灯

        头文件:semaphore.h

        原型:

                int sem_wait(sem_t *sem);---阻塞

                        当去申请一个信号量的时候,假如能申请到,则返回,假如申请不到,则阻塞。

                int sem_trywait(sem_t *sem);--非阻塞

                        当去申请一个信号量的时候,无论能不能申请成功都返回,我们可以通过他的返回值来判断申请成功或者是失败。

        参数:sem_t *sem, :信号灯的核心结构体

        返回值:成功返回 0      失败返回  非零

+++++++++++++++++++++++++++++++++++++++++++++++++++++++

sem_post():v操作,释放一个信号灯

        头文件:semaphore.h

        原型:int sem_post(sem_t *sem);

        参数:sem_t *sem, :信号灯的核心结构体

        返回值:成功返回 0      失败返回  非零

+++++++++++++++++++++++++++++++++++++++++++++++++++++++

sem_destroy():销毁一个信号灯

        头文件:semaphore.h

        原型:int sem_destroy(sem_t *sem);

        参数:sem_t *sem, :信号灯的核心结构体

8.线程间的通讯

1)直接共享进程的资源(利用全局变量)

2)信号,pthread_kill();

        pthread_kill():向某个线程发送一个信号

                头文件:signal.h

                原型:int pthread_kill(pthread_t pd,int sig)

                参数:

                        pthread_t pd:线程id

                        int sig:发送的信号

                函数的返回值:成功返回  0    失败返回  非零

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

编程小白菜123

你的鼓励将是我创作的最大动力

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

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

打赏作者

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

抵扣说明:

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

余额充值