`
weihe6666
  • 浏览: 441842 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
社区版块
存档分类
最新评论

浅析Posix信号灯

    博客分类:
  • UNIX
 
阅读更多
Posix信号灯


信号灯分为有名信号灯和内存信号灯,本文只讲有名信号灯。

一 有名信号灯API

1.sem_open

函数原形:sem_t *sem_open(const char *name,int oflag,/*mode_t mode,unsigned int value*/);

参数:
name  信号灯的外部名字
oflag  选择创建或打开一个现有的信号灯
mode 权限位
value 信号灯初始值,二值信号灯为1,非二值信号灯大于1
返回值:
成功时返回指向信号灯的指针,出错时为SEM_FAILED

2.sem_close

#include<semaphore.h>
int sem_close(sem_t *sem);

返回:成功是返回0,出错是返回-1

一个进程终止时,内核对其上的仍然打开的所有的有名信号灯自动执行sem_close操作,即关闭信号灯。不论该进程是自愿终止的还是非自愿终止的,这种关闭动作都会发生。

关闭一个信号灯并内有将它从系统中删除。这就是说,Posix有名信号灯至少是随内核持续的:即使当前没有进程打开着某个信号灯,它的值仍然保存。

3.sem_unlink

#include<semaphore.h>
int sem_unlink(const char*name);

有名信号使用sem_unlink从系统中删除。

4.sem_wait
#include<semaphore.h>
int sem_wait(sem_t *sem);
int sem_trywait(sem_t *sem);

sem_wait函数测试所指定信号灯的值,如果该值大于0,那就将它减1,并立即返回。如果该值等于0,调用线程就被投入休眠中,即被挂起,直到其值大于0,这时再将它减1,函数随后返回。

注意这里的机制和互斥锁和条件变量的不同,条件变量是和互斥锁合在一起的,条件变量主要是对公共资源的上锁和解锁来进行同步,而信号灯主要是对灯的值进行判断,根据其大于或小于0进行同步操作。

sem_trywait当灯值为0时,并不将调用线程投入休眠,而是返回EAGAIN错误。

5.sem_post

#include<semaphore.h>
int sem_post(sem_t *sem);

当一个线程使用完某个信号灯时,它调用sem_post。使信号灯的数值加1,然户唤醒正在等待信号灯数值变为正数的任意线程

6.sem_getvalue

#include<semaphore.h>
int sem_getvalue(sem_t *sem,int value);

返回所指定信号灯的当前值,如果信号灯当前值以上锁,那么返回或为0,或为某个负数,其绝对值等于该信号灯解锁的线程数。

现在看出了互斥锁、条件变量和信号灯之间的差别。首先:互斥锁必须有给它上锁的线程进行解锁,而信号灯没有这限制。其次,每个信号灯有一个与它相关联的数值,它由挂出函数加1sem_post,由等待函数减1即sem_wait,即使当时没有线程在等待信号灯由0变为正数,该信号灯同样可以挂出该信号灯。而条件变量某个线程调用了pthread_cond_signal,若当时没有线程阻塞在pthread_cond_wait调用中,那么此信号将丢失。

二,实例
  1 #include<semaphore.h>
  2 #include<unistd.h>
  3 #include<stdio.h>
  4 #include<stdlib.h>
  5 #include<fcntl.h>
  6 #include<pthread.h>
  7 #include<sys/types.h>
  8 #include <sys/syscall.h>
  9 #define gettid()(syscall(__NR_gettid ))
 10 
 11 void *thread_function(void*arg);
 12 void print(pid_t);
 13 sem_t *sem;//deine semaphore
 14 int val; //semaphore value
 15 
 16 int main(int argc,char ** argv){
 17 
 18     pthread_t a_thread;
 19     int n = 0;
 20     if(argc != 2){
 21         printf("please input a file name!\n");
 22         exit(1);
 23     }
  24 
 25     sem = sem_open(argv[1],O_CREAT,0644,3);//open semaphore
 26 
 27     while(n++ < 5){
 28         if((pthread_create(&a_thread,NULL,thread_function,NULL)) != 0){
 29             printf("Thread create failed\n");
 30             exit(1);
 31         }
 32     }
 33 
 34     pthread_join(a_thread,NULL);
 35     sem_close(sem);
 36     sem_unlink(argv[1]);
 37 }
 38 
 39 void *thread_function(void *arg){
 40     sem_wait(sem);
 41     pid_t pid;
 42     pid = gettid();
 43     print(pid);
 44     sleep(1);
 45     sem_post(sem);
 46     printf("I'm finished,my tid is %d\n",pid);
 47 }
 48 
 49 void print(pid_t pid){
 50     printf("I get it,my tid is %d\n",pid);
 51 
 52     sem_getvalue(sem,&val);
 53     printf("Now the value is %d\n",val);
 54 }                                                                


输出为:
I get it,my tid is 3158
Now the value is 0
I get it,my tid is 3159
Now the value is 0
I get it,my tid is 3160
Now the value is 0
I'm finished,my tid is 3158
I get it,my tid is 3162
Now the value is 1
I'm finished,my tid is 3159
I'm finished,my tid is 3160
I get it,my tid is 3161
Now the value is 1
I'm finished,my tid is 3162


解析:
I get it,my tid is 3158
Now the value is 0
I get it,my tid is 3159
Now the value is 0
I get it,my tid is 3160
Now the value is 0

ID为3158、3159、3160的三各进程首先调用sem_wait将信号灯减1,那么此时的信号灯数值变为0,这就意为着其它进程无法使用信号灯,只有调用sem_wait进入休眠状态,等待信号灯数值变为正数。

I'm finished,my tid is 3158:这时ID为3158的进程调用sem_post将信号灯数值加1,并唤醒处于休眠状态的任意其它进程。

I get it,my tid is 3162:这时ID为3158进程唤醒的,它同样调用sem_wait将信号灯挂起,即将信号灯数值减去1,此时信号灯的数值又变为0.

Now the value is 1:这句是ID为3158进程调用sem_post后将信号灯数值加1之后的输出。

I'm finished,my tid is 3159
I'm finished,my tid is 3160
他们是:ID为3159和3160进程调用sem_post后将信号灯数值加1后的输出,此时信号灯的数值为2,他们将唤醒另外的处于休眠的进程。

I get it,my tid is 3161:此进程被唤醒。

I'm finished,my tid is 3162:ID为3162的进程结束。
分享到:
评论

相关推荐

    Linux信号灯C语言编程示例(包含信号灯回滚,信号等取值和初始化操作)

    这个结构体可能包含一个整型变量`value`,表示信号灯的当前值,以及用于内核级信号灯操作的内核句柄(例如在POSIX系统中是`sem_t`)。 2. 函数原型: - `int init_sem(struct semaphore *sem, int value)`:初始化...

    coffeecatch,coffeecatch,一个小型的本地posix信号捕捉器(特别适用于android/dalvik上的jni代码).zip

    《Coffeecatch:本地POSIX信号捕捉器在Android/Dalvik中的应用》 Coffeecatch是一款小巧而实用的本地POSIX信号捕捉器,它专为在Android/Dalvik环境中运行的JNI(Java Native Interface)代码设计。POSIX信号是操作...

    8_posix_signal

    POSIX信号(POSIX Signals)是其中的一种机制,它允许一个进程通知另一个进程发生了特定事件或需要采取某种行动。这个“8_posix_signal”压缩包文件很可能包含了与实现POSIX信号相关的代码示例,可能来源于CSDN博主...

    Simple-Windows-Posix-Semaphore:一个简单的窗口 POSIX 信号量库

    适用于 Windows 的简单 POSIX 信号量 POSIX 信号量允许进程和线程同步它们的动作。 信号量是一个整数,其值决不允​​许低于零。 可以对信号量执行两种操作:将信号量值加一 [ sem_post ]; 并将信号量值减一 [ sem_...

    posix-semaphore:阻止 Node.js 的 POSIX 信号量

    posix信号量 安装 npm install posix-semaphore 例子 const Semaphore = require ( 'posix-semaphore' ) const sem = new Semaphore ( 'mySemaphore' ) sem . acquire ( ) /* my code using shared ressources :...

    example_posix:ProducerConsumer 问题使用(POSIX 信号量和线程)

    生产者/消费者问题使用(POSIX 信号量和线程) 获取文件: 在实验室计算机上,使用以下命令: git clone git://github.com/cwru-eecs338/example_posix.git 课程: 创建和管理 POSIX 线程和信号量。 从多个 ...

    posix官方相关文档

    POSIX Base Definitions.pdf POSIX Base Specifications, Issue 7.pdf POSIX Rationale (Informative).pdf POSIX Realtime and Embedded Application Support.pdf(IEEE std 1003.13-2003) POSIX Shell and ...

    并行计算 + Posix

    4. **Posix信号**:介绍如何使用信号进行进程间的通信和错误处理,如SIGINT、SIGTERM和SIGKILL等。 5. **Posix时间与定时器**:讲解时间相关的函数(如time、sleep、alarm、clock_gettime等),以及如何使用定时器...

    mingw_x86_64-posix-seh

    “posix-seh”则指的是POSIX信号处理(Signal Handling)和Windows的结构化异常处理(Structured Exception Handling)的结合。在MingW中,选择POSIX信号处理模式允许开发者使用更符合Unix/Linux编程习惯的异常处理...

    POSIX标准以及函数接口查询

    POSIX(Portable Operating System Interface,可移植操作系统接口)是一组国际标准,定义了操作系统与应用程序之间的接口,旨在确保跨多种Unix和其他类Unix系统的一致性和兼容性。这一标准由IEEE(电气和电子工程师...

    Posix标准接口文档(英文版).pdf

    其中,Linux系统接口文档部分详细描述了Linux如何实现POSIX标准,包括信号处理、进程控制、内存管理、文件操作、网络编程等方面的接口。 例如,POSIX标准定义了fork()函数用于创建新进程,exec()系列函数用于替换...

    POSIX 官方正式 标准 (内含8个文档)

    POSIX Base Definitions;POSIX Base Specifications, Issue 7;POSIX Rationale (Informative);POSIX® Realtime and Emeded Application Support;POSIX® Shell and Utilities;POSIX System Interfaces;POSIX ...

    linux系统下多线程编程文档资料

    二、关于posix有名信号灯使用的几点注意 24 三、posix有名信号灯应用于多线程 25 四、posix有名信号灯应用于多进程 27 五、基于内存的信号灯 29 第四章 互斥量 39 一、什么是互斥锁 39 二、初始化/回收互斥锁 40 三...

    Posix(1).rar_POSIX Pthread_posix_pthread_pthread posix

    4. **同步机制**:pthreads提供多种同步原语,包括互斥锁(`pthread_mutex_t`)、条件变量(`pthread_cond_t`)、读写锁(`pthread_rwlock_t`)和信号量(`sem_t`),用于控制对共享资源的访问。 5. **线程调度**:...

    POSIX多线程程序设计.pdf

    《POSIX多线程程序设计》深入描述了IEEE的开放系统接口标准——POSIX线程,通常称为Pthreads标准。本书首先解释了线程的基本概念,包括异步编程、线程的生命周期和同步机制;然后讨论了一些高级话题,包括属性对象、...

    4_posix_sem.tgz

    POSIX信号量(POSIX Semaphores)是实现这种同步的一种机制,它提供了计数信号量和二进制信号量两种类型。这个名为"4_posix_sem.tgz"的压缩包文件包含了与使用POSIX信号量相关的源代码示例,主要分为"4_posix_sem_...

    x86_64-8.1.0-release-posix-seh-rt_v6-rev0.rar

    3. **POSIX兼容性**:由于使用了POSIX信号处理,开发者可以使用与Unix/Linux平台类似的错误处理机制,但要注意Windows的SEH和POSIX信号处理之间的差异。 4. **运行时库**:rt_v6可能是指MinGW-w64的运行时库,这个...

    Micrium_POSIX.tar_feeloru_rtos_Micrium_POSIX_

    这个内核以其小巧、高效著称,支持抢占式调度、任务管理、信号量、消息队列等功能,满足了实时系统的需求。通过这些接口,开发者可以创建和管理线程,进行同步和通信,同时保持与标准POSIX API的兼容性。 Linux作为...

    posix 接口 入门资料

    POSIX(Portable Operating System Interface)接口是一套标准,旨在确保不同UNIX系统间的源代码可移植性。这个入门资料集合包含了多个资源,可以帮助你深入理解和掌握POSIX接口在UNIX和类UNIX系统,如Linux中的应用...

    最新版免费 POSIX 标准文档

    最新版免费 POSIX 标准文档,下载即用.POSIX表示可移植操作系统接口(Portable Operating System Interface of UNIX,缩写为 POSIX ),POSIX标准定义了操作系统应该为应用程序提供的接口标准,是IEEE为要在各种UNIX...

Global site tag (gtag.js) - Google Analytics