信号量

Linux 信号量使用方法

风流意气都作罢 提交于 2020-01-18 04:06:48
信号量和互斥锁(mutex)的区别:互斥锁只允许一个线程进入临界区,而信号量允许多个线程同时进入临界区。 不多做解释,要使用信号量同步,需要包含头文件semaphore.h。 主要用到的函数: int sem_init(sem_t *sem, int pshared, unsigned int value); 其中 sem 是要初始化的信号量, pshared 表示此信号量是在进程间共享还是线程间共享,value是信号量的初始值。 int sem_destroy(sem_t *sem); ,其中 sem 是要销毁的信号量。只有用 sem_init 初始化的信号量才能用 sem_destroy 销毁。 int sem_wait(sem_t *sem); 等待信号量,如果信号量的值大于0,将信号量的值减1,立即返回。如果信号量的值为0,则线程阻塞。相当于P操作。成功返回0,失败返回-1。 int sem_post(sem_t *sem); 释放信号量,让信号量的值加1。相当于V操作。 //用户从终端输入任意字符然后统计个数显示,输入end则结束 //使用多线程实现:主线程获取用户输入并判断是否退出,子线程计数 #include<stdio.h> #include <pthread.h> #include<stdlib.h> #include <string.h> #include

杂七杂八小知识

允我心安 提交于 2020-01-17 13:59:11
最近在使用多线程,模仿技术总监的写法自定义了一个多线程控制类。该类是根据自定义的数量从线程池中开启多个线程,然后最后使用waithandle.waitall()来等待线程的全部完成。但是在实际测试中发现,不能直接在sta线程中调用该方法,需要单独开一个线程来等待全部线程结束,具体原因未知。有类似于该类的功能还有semphone 信号量,该信号量可以决定同时有多少个线程去执行程序,每开启一个线程,就new 一个 ManualResetEventSlim用来判断当前线程是否结束,当某个工作线程结束时,可以将信号量结束一次,以便开启下一个线程,同时结束当前线程的ManualResetEventSlim。在最后判断全部ManualResetEventSlim是否结束用来决定整个工作是否完成。 关于ManualResetEventSlim和ManualResetEvent的区别,还在研究中 来源: CSDN 作者: mosse9999 链接: https://blog.csdn.net/mosse9999/article/details/104015822

Linux进程管理: 多进程编程

六眼飞鱼酱① 提交于 2020-01-17 02:13:11
多进程编程 mind-Mapping 保存有xmind原始文件,可直接获取 无名管道PIPE 命名管道FIFO POSIX共享内存 POSIX消息队列 POSIX信号量 SYS V共享内存 SYS V消息队列 SYS V信号量 来源: CSDN 作者: Z_Stand 链接: https://blog.csdn.net/Z_Stand/article/details/104011127

多线程之间信号量

丶灬走出姿态 提交于 2020-01-16 10:01:32
1. 什么是信号量 linux sem 信号量是一种特殊的变量,访问具有原子性, 用于解决进程或线程间共享资源引发的同步问题。 用户态进程对 sem 信号量可以有以下两种操作: 等待信号量 当信号量值为 0 时,程序等待;当信号量值大于 0 时,信号量减 1,程序继续运行。 发送信号量 将信号量值加 1 通过对信号量的控制,从而实现共享资源的顺序访问。 2. 相关函数说明 linux 信号量相关函数都声明头文件 semaphore.h 头文件中,所以使用信号量之前需要先包含头文件 #include <semaphore.h> 1 信号量的创建就像声明一般的变量一样简单,例如:sem_t sem,之后对该信号量进行初始化和使用。 2.1 sem_init 该函数用于创建信号量,其原型如下: int sem_init(sem_t *sem, int pshared, unsigned int value); 1 该函数初始化由 sem 指向的信号对象,并给它一个初始的整数值 value。 pshared 控制信号量的类型,值为 0 代表该信号量用于多线程间的同步,值如果大于 0 表示可以共享,用于多个相关进程间的同步 参数 pshared > 0 时指定了 sem 处于共享内存区域,所以可以在进程间共享该变量 2.2 sem_wait int sem_wait(sem_t *sem);

【驱动】同步、互斥、阻塞

杀马特。学长 韩版系。学妹 提交于 2020-01-15 21:55:47
1. 原子操作 原子操作指的是在执行过程中不会被别的代码路径所中断的操作。 常用原子操作函数举例: atomic_t v = ATOMIC_INIT(0); //定义原子变量v并初始化为0 atomic_read(atomic_t *v); //返回原子变量的值 void atomic_inc(atomic_t *v); //原子变量增加1 void atomic_dec(atomic_t *v); //原子变量减少1 int atomic_dec_and_test(atomic_t *v); //自减操作后测试其是否为0,为0则返回true,否则返回false。 2. 信号量 信号量(semaphore)是用于保护临界区的一种常用方法,只有得到信号量的进程才能执行临界区代码。 当获取不到信号量时,进程进入休眠等待状态。   定义信号量   struct semaphore sem;   初始化信号量   void sema_init (struct semaphore *sem, int val);   void init_MUTEX(struct semaphore *sem);//初始化为0 以上三句指令等价于:   static DECLARE_MUTEX(button_lock); //定义互斥锁 获得信号量 void down(struct semaphore *

进程的同步与互斥

帅比萌擦擦* 提交于 2020-01-15 05:39:49
在操作系统中,进程是占有资源的最小单位。 临界资源是指系统中一次只允许一个进程使用的资源(可以是硬件资源像打印机,也包括软件资源,如程序中的数据结构、表格和变量、文件等。)访问临界资源的那段代码称为临界区。 进程同步:它主要源于进程合作,是进程间共同完成一项任务时直接发生相互作用的关系。为进程之间的直接制约关系。 比如说进程A需要从缓冲区读取进程B产生的信息,当缓冲区为空时,进程B因为读取不到信息而被阻塞。而当进程A产生信息放入缓冲区时,进程B才会被唤醒。 进程互斥:主要源于资源共享,是进程之间的间接制约关系。 进程互斥就是保证每次只有一个进程使用临界资源。 比如进程B需要访问打印机,但此时进程A占有了打印机,进程B会被阻塞,直到进程A释放了打印机资源,进程B才可以继续执行。 同步和互斥这两种制约关系的区别: 进程的互斥是进程间竞争共享资源的使用权,这种竞争没有固定的必然关系;而进程同步时,涉及到共享资源的并发进程之间有一种必然的依赖关系。 使用系统中的临界资源时,诸进程应采取互斥方式,实现对资源的共享。为实现进程互斥的进入自己的临界区,可用软件方法,但更多的是在系统中设置专门的同步机制来协调各进程间的运行。所有的同步机制都应遵循以下四条准则: (1)空闲让进:因为,当无进程处于临界区时,表明临界资源处于空闲状态,应允许一个请求进入临界区的进程立即进入自己的临界区

python线程

好久不见. 提交于 2020-01-15 03:31:16
"""线程"""进程是内存分配的最小单位,线程是调度的最小单位。每个进程中至少有一个线程"""线程与进程的区别: 进程相互独立,同一进程的各个线程间资源共享,某进程内的线程在其他进程内不可见。 进程间通信IPC,线程可以直接读写进程数据段来进行通信-需要同步和互斥锁等,保证数据的一致性。 线程上下文切换比进程快很多 在多线程操作系统中进程不是一个可执行的实体 python的线程模块常用thread、threading,threading提供更高级的线程管理建议使用。 查看treading.Tread的类可知参数 def __init__(self, group=None, target=None, name=None, args=(), kwargs=None, *, daemon=None): target是函数 name是线程名""" 开启线程 1 import threading 2 3 def product(number): 4 print(number,) 5 6 thread_lst = [] 7 #开启100线程 8 for i in range(100): 9 t = threading.Thread(target=product,args=(i,)) 10 t.start() #执行start开启线程 11 thread_lst.append(t) 12 13

线程认识

落爺英雄遲暮 提交于 2020-01-14 08:37:30
线程是为了让程序更好的利用cpu资源,在并行/并发处理下比进程切换cpu使用所要的花销要小。 在一个程序里的一个执行路线就叫做线程(thread)。更准确的定义是:线程是“一个进程内部的控制序列”。一切进程至少都有一个执行线程。线程在进程内部运行,本质是在进程地址空间内运行。在Linux系统中,在CPU眼中,看到的PCB都要比传统的进程更加轻量化( Linux中可以称为轻量级进程(LWP) )。透过进程虚拟地址空间,可以看到进程的大部分资源,将进程资源合理分配给每个执行流,就形成了线程执行流。 结合生活中的例子,创建一个进程就相当于工厂新建了一个厂子, 而创建一个线程就相当于在原厂的基础上增加一条生产线 ,在这方面也能看出创建新进程会分配新的虚拟地址空间,而 创建新的线程则会共用原来的虚拟地址空间(创建进程会拷贝原有的PCB并指向原有的虚拟地址空间) 。那么进程和线程的区别是什么呢?进程的作用更多是资源的管理(管理内存、文件),而 线程的作用更多是负责资源的调度和执行(也是抢占式的调度)。 ------>线程之间共用虚拟地址空间和文件描述符表 ------>线程之间不共用的资源:①栈(函数调用栈、局部变量),每个线程的栈是不共用的但不是私有的,别的线程也可以用②上下文信息(cpu中寄存器数据保存在内存中,方便下次执行)③errno错误码

线程认识

我的未来我决定 提交于 2020-01-14 08:37:20
线程是为了让程序更好的利用cpu资源,在并行/并发处理下比进程切换cpu使用所要的花销要小。 在一个程序里的一个执行路线就叫做线程(thread)。更准确的定义是:线程是“一个进程内部的控制序列”。一切进程至少都有一个执行线程。线程在进程内部运行,本质是在进程地址空间内运行。在Linux系统中,在CPU眼中,看到的PCB都要比传统的进程更加轻量化( Linux中可以称为轻量级进程(LWP) )。透过进程虚拟地址空间,可以看到进程的大部分资源,将进程资源合理分配给每个执行流,就形成了线程执行流。 结合生活中的例子,创建一个进程就相当于工厂新建了一个厂子, 而创建一个线程就相当于在原厂的基础上增加一条生产线 ,在这方面也能看出创建新进程会分配新的虚拟地址空间,而 创建新的线程则会共用原来的虚拟地址空间(创建进程会拷贝原有的PCB并指向原有的虚拟地址空间) 。那么进程和线程的区别是什么呢?进程的作用更多是资源的管理(管理内存、文件),而 线程的作用更多是负责资源的调度和执行(也是抢占式的调度)。 ------>线程之间共用虚拟地址空间和文件描述符表 ------>线程之间不共用的资源:①栈(函数调用栈、局部变量),每个线程的栈是不共用的但不是私有的,别的线程也可以用②上下文信息(cpu中寄存器数据保存在内存中,方便下次执行)③errno错误码

多线程(二)

谁都会走 提交于 2020-01-14 02:20:23
简易阻止:Sleep,阻止给定的时间周期;Join,等待另一个线程完成。 一旦被阻止,线程立刻放弃分配给他的CPU资源,并且ThreadState属性值改为WaitSleepJoin。 停止阻止的方式:(1)操作超时(2)通过Thread的Interrupt中断了(3)通过Thread的Abort放弃了. Thread.Sleep(Timeout.Infinite);//休眠直到中断 Thread.Sleep(TimeSpan.FromSeconds(1));//休眠一秒 Thread.Sleep(0);//暂时的放弃CPU,时间刚刚够其他时间片里的线程执行。 Join方法也接收一个使用毫秒或用TimeSpan类的超时参数,当Join超时时返回false,如果线程已终止,则返回true。(在阻止是Join保持信息汲取,sleep停止信息汲取)。 锁系统:lock,确保只有一个线程访问某资源,不能跨进程,速度快; Mutex, ,确保只有一个线程访问某资源,可以跨进程,速度中等; Semaphore,不超过制定数目的线程访问某资源,可以跨进程,速度中等。 任何对所有有关系的线程都可见的对象都可以作为同步对象,但要服从一个硬性规定:它必须是引用类型。也强烈建议同步对象最好私有在类里面(比如一个私有实例字段)防止无意间从外部锁定相同的对象。服从这些规则,同步对象可以兼对象和保护两种作用。