信号量 sem_t 进程同步
sem_t分为有名和无名。有名的sem_t通过sem_open来创建, 而无名的sem_t通过sem_init的初始化。 用有名的sem_t来进程间同步是件很容易的事情,百度上一搜很多想相关的例子。
有名和无名的sem_t主要区别:
1. 效率:有名sem_t是放在文件,无名的sem_t是放在内存。
2.限制:有名的sem_t可以用来同步多线程,任意多进程。而无名的sem_t可以用来同步多线程,以及Fork出来的进程间的同步。
网上想关的例子很多,本文主要是测试一下用无名sem_t进程同步,比如你在使用nginx的时候,nginx会fork出很多works,如果在works间你希望能同步一些操作,那么这个时候就可以用它,注意下面API描述中的红色部分,明确说了需要放到共享内存(shared memory)。
Name
sem_init - initialize an unnamed semaphore
Synopsis #include <semaphore.h>
int sem_init(sem_t *sem, int pshared, unsigned int value);
Link with -pthread.
Description sem_init() initializes the unnamed semaphore at the address pointed to by sem. The value argument specifies the initial value for the semaphore.
The pshared argument indicates whether this semaphore is to be shared between the threads of a process, or between processes. If pshared has the value 0, then the semaphore is shared between the threads of a process, and should be located at some address that is visible to all threads (e.g., a global variable, or a variable allocated dynamically on the heap).
If pshared is nonzero, then the semaphore is shared between processes, and should be located in a region of shared memory (see shm_open(3), mmap(2), and shmget(2)). (Since a child created by fork(2) inherits its parent's memory mappings, it can also access the semaphore.) Any process that can access the shared memory region can operate on the semaphore using sem_post(3), sem_wait(3), etc. Initializing a semaphore that has already been initialized results in undefined behavior.
下面是一段简单的测试代码
#include <semaphore.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/mman.h> void *createSharedMemory(size_t size) {
void *addr = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_ANON | MAP_SHARED, -, );
if (addr == MAP_FAILED) {
return NULL;
}
return addr;
} void freeSharedMemory(void *addr, size_t size)
{
if (munmap(addr, size) == -) {
printf("munmap(%p, %d) failed", addr, (int)size);
}
} int main(int argc, char *argv[] ) { sem_t* mutex_share = createSharedMemory(sizeof(sem_t));
sem_t mutex_not_share;
if (mutex_share == NULL) {
printf("creat share memory error\n");
return ;
}
if( sem_init(mutex_share,,) < || sem_init(&mutex_not_share,,) < ) {
printf("semaphore initilization\n");
return ;
}
if (fork() == ) {
sem_wait(&mutex_not_share);
for(int j = ;j<;j++) {
printf("mutex_not_share child j = %d\n", j);
usleep();
}
sem_post(&mutex_not_share); sem_wait(mutex_share);
for (int i = ;i<;i++) {
printf("mutex_share child i = %d\n", i);
usleep();
}
sem_post(mutex_share); }
else {
sem_wait(&mutex_not_share);
for(int j = ;j<;j++) {
printf("mutex_not_share parent j = %d\n", j);
usleep();
}
sem_post(&mutex_not_share);
sem_wait(mutex_share);
for (int i = ;i<;i++) {
printf("mutex_share parent i = %d\n", i);
usleep();
}
sem_post(mutex_share);
}
freeSharedMemory(mutex_share,sizeof(sem_t));
return ;
}
运行结果可以看出,如果没有放到共享内存,就算将pshared设置为1,也起不了作用。

信号量 sem_t 进程同步的更多相关文章
- 信号量进程同步,王明学learn
信号量进程同步 一组并发进程进行互相合作.互相等待,使得各进程按一定的顺序执行的过程称为进程间的同步. 信号量在进程同步时初始值为:0 信号量在进程互斥时初始值为:大于0的 本章节主要使用信号量,使的 ...
- system V信号量和Posix信号量
一.函数上的区别 信号量有两种实现:传统的System V信号量和新的POSIX信号量.它们所提供的函数很容易被区分:对于所有System V信号量函数,在它们的名字里面没有下划线.例如,应该是sem ...
- Linux 多线程信号量同步
PV原子操作 P操作: 如果有可用的资源(信号量值>0),则此操作所在的进程占用一个资源(此时信号量值减1,进入临界区代码); 如果没有可用的资源(信号量值=0),则此操作所在的进程被阻塞直到系 ...
- [转]一个简单的Linux多线程例子 带你洞悉互斥量 信号量 条件变量编程
一个简单的Linux多线程例子 带你洞悉互斥量 信号量 条件变量编程 希望此文能给初学多线程编程的朋友带来帮助,也希望牛人多多指出错误. 另外感谢以下链接的作者给予,给我的学习带来了很大帮助 http ...
- 关于Linux下进程间使用共享内存和信号量通信的时的编译问题
今天在编译一个使用信号量实现进程同步时,出现了库函数不存在的问题.如下图 编译结果实际上是说,没include相应的头文件,或是头文件不存在(即系统不支持该库函数) 但我man shm_open是可以 ...
- 线程间同步之 semaphore(信号量)
原文地址:http://www.cnblogs.com/yuqilin/archive/2011/10/16/2214429.html semaphore 可用于进程间同步也可用于同一个进程间的线程同 ...
- Linux多线程实践(5) --Posix信号量与互斥量解决生产者消费者问题
Posix信号量 Posix 信号量 有名信号量 无名信号量 sem_open sem_init sem_close sem_destroy sem_unlink sem_wait sem_post ...
- linux POSIX 信号量介绍
信号量一.什么是信号量信号量的使用主要是用来保护共享资源,使得资源在一个时刻只有一个进程(线程)使用.多线程可以同时运行多个线程函数完成功能,但是对于共享数据如果不加以锁定,随意改变共享数据的值会发生 ...
- Linux多线程--使用信号量同步线程【转】
本文转载自:http://blog.csdn.net/ljianhui/article/details/10813469 信号量.同步这些名词在进程间通信时就已经说过,在这里它们的意思是相同的,只不过 ...
随机推荐
- System.Threading.Timer 使用
//定义计时器执行完成后的回调函数 TimerCallback timecallback = new TimerCallback(WriteMsg); //定义计时器 System.Threading ...
- caffe源代码分析--math_functions.cu代码研究
当中用到一个宏定义CUDA_KERNEL_LOOP 在common.hpp中有. #defineCUDA_KERNEL_LOOP(i,n) \ for(inti = blockIdx.x * bloc ...
- 如何在myeclipse8.5中使用maven
今天搞了一天才搞清楚这个问题,一直导入不了mavendependencies,后来发现是 13-11-23 下午06时47分11秒: Downloading http://mirrors.ibibli ...
- 浅析mysql 共享表空间与独享表空间以及他们之间的转化
innodb这种引擎,与MYISAM引擎的区别很大.特别是它的数据存储格式等.对于innodb的数据结构,首先要解决两个概念性的问题: 共享表空间以及独占表空间.什么是共享表空间和独占表空间共 ...
- The builder launch configuration could not be found
Export Wizard Error Errors occurred during the build Problems occured when invoking code from p ...
- Python简易爬虫
经常需要下载论文,每次都需要去网页上搜索,然后点击下载,实在麻烦,正好最近刚入门Python,心血来潮,想着写一个爬虫 经过一天查阅资料,基本算是完成了,但是还是不足,比如对知网和万方暂时还不行,但是 ...
- Interpreter Expression 解释器模式
简介 Interpreter模式也叫解释器模式,是由GoF提出的23种设计模式中的一种.Interpreter是行为模式之一,它是一种特殊的设计模式,它建立一个解释器,对于特定的计算机程序设计语言,用 ...
- codevs 1282 约瑟夫问题(线段树)
#include<iostream> #include<cstdio> #include<cstring> #define maxn 30010 using nam ...
- HDU3480
题意:给你n个数,然后让你分成m个集合,每个集合有一个值(最大值减最小值,然后平方),求整个集合的可能最小值. 思路:因为每个集合里的值只和最大和最小值有关,所以很容易想到先排序,然后用DP可求得解, ...
- Android虚拟机GenyMotion-- 遇到的问题
问题: android studio 检测不到 genymotion 原因:没有设置genymotion的adb,也就是sdk的路径. 解决方法:打开genymotion的主页面,设置sdk的位置为你 ...