线程间同步机制

多线程编程中,同步机制用于协调多个线程对共享资源的访问,防止数据竞争和不一致

同步方式:信号量。

信号量是一个计数器,用于控制多个线程/进程对有限资源的访问,是实现线程同步和互斥的重要机制。

信号量 = 一个计数器 + 等待队列

概念 说明
计数值 表示可用资源的数量
P操作(wait) 申请资源,计数值减1(如果为0则等待)
V操作(post) 释放资源,计数值加1(唤醒等待者)

死锁

死锁:死锁指的是在多线程环境中,每个执行流(线程)都有未释放的资源,且互相请求对方未释放资源,从而导致陷入永久等待状态的情况。
	现象:
	现象1:忘记释放锁
	现象2:重复加锁
	现象3:多线程多锁,抢占锁资源不当
	如:线程A获取了1锁,线程B获取了2锁,同时线程A还想获取2锁,线程B还想获取1锁

*产生死锁的四个必要条件(四条全中 = 死锁,破掉任意一条 = 解除):
	(1) 互斥条件:一个资源同一时刻只能被一个任务占用(一个执行流获取锁后,其它执行流不能再获取该锁)。
	(2) 请求与保持条件:已经拿着一部分资源不释放,同时又去申请新的资源(执行流本身使用着一把锁并不释放,还在请求别的锁)。
	(3) 不剥夺条件:资源只能由持有者主动释放,系统/其他任务不能强行抢过来(A执行流拿着锁,其它执行流不能释放)。
	(4) 循环等待条件:若干进程之间形成一种头尾相接的循环等待资源关系(多个执行流拿着对方想要的锁,并且各执行流还去请求对方的锁)。

	解决方法:
	1.锁一定要成对出现
	2.使线程的加解锁顺序一致
	3.破坏环路等待条件
	  使用非阻塞锁,一旦线程发现请求的锁被使用,就去释放自己拥有的资源

进程间通信(IPC)

进程间通信(IPC)是指不同进程之间交换数据的机制。由于进程地址空间相互独立,需要特殊机制来实现通信。

方法 特点 适用场景 复杂度
管道 单向,简单 父子进程通信
命名管道(FIFO) 单向,有文件名 无关进程通信
消息队列 消息结构,有优先级 异步通信
共享内存 最快,无同步 大量数据快速交换
信号量 同步机制 资源控制
信号 异步通知 事件通知
套接字 网络通信 不同主机进程
单工 单向通道,只能一个方向
半双工 双向通道,但同一时间只能一个方向
全双工 双向通道,可以同时双向传输
管道 半双工,一端读一端写
双管道 可以实现全双工通信

管道(Pipe)

最简单的IPC方式,单向父子进程之间使用。

#include <sched.h>
#include <stdio.h>
#include <unistd.h>
#include "head.h"

//pipefd[0]  ---> read
//pipefd[1]  ---> write
int main(int argc,const char*argv[])
{
    int pipefd[2];
    int ret = pipe(pipefd);//创建一个无名管道并获得两个文件描述符
    if(0!=ret)
    {
        perror("pipe error");
        return -1;
    }

    pid_t pid=fork();
    if(pid>0)
    {
        close(pipefd[0]);
        write(pipefd[1],"kskblzdjd",11);
        wait(NULL);
        close(pipefd[1]);
    }
    else if(0==pid)
    {
        char buff[512]={0};
        close(pipefd[1]);
        read(pipefd[0],buff,sizeof(buff));
        printf("%s\n",buff);
        close(pipefd[0]);
    }
    else
    {
        perror("error");
    }
    return 0;
}

注意:

  1. 管道在使用时要确定它的方向,是一个单向的数据通道
  2. 管道中的数据,一旦被读走,直接剪切走数据
  3. 管道中的数据遵循先进先出的特点(FIFO)、
  4. 管道默认大小65536字节,64k。
  5. 管道的读端和写端不能交换。

管道的特点:

  1. 读阻塞:当读写端都存在时,从管道中读数据,管道为空时,发生读阻塞

  2. 写阻塞:当管道读写段都存在时,向管道中写数据,管道满时,发生写阻塞

  3. 管道破裂:当读端关闭,向管道中写入数据时,发生管道破裂(异常)

  4. 读返回0:当写端关闭,读管道时,管道中有数据则读出数据,没有数据,则读不发生阻塞,直接返回0

Logo

汇聚全球AI编程工具,助力开发者即刻编程。

更多推荐