信号量 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 信号量.同步这些名词在进程间通信时就已经说过,在这里它们的意思是相同的,只不过 ...
随机推荐
- hdu 3553 Just a String (后缀数组)
hdu 3553 Just a String (后缀数组) 题意:很简单,问一个字符串的第k大的子串是谁. 解题思路:后缀数组.先预处理一遍,把能算的都算出来.将后缀按sa排序,假如我们知道答案在那个 ...
- 使用Java Mail发送邮件
本笔记参考自:高爽|Coder,原文地址:http://blog.csdn.net/ghsau/article/details/17839983 JavaMail是SUN提供给开发人员在应用程序中实现 ...
- 安卓在SQLiteOpenHelper类进行版本升级和降级
一.升级(使用到onUpgrade()方法和onCreate()没有安装过才用到) 简单理一下思路: v1.0 (也就是说第一次使用这软件,没有安装过 所有在onCreate() 方法里写代码) ...
- 2016最新cocoapods版本更新,以及多个版本的问题
先删除之前的pod 在终端中执行下面命令. 删除目录下的podrm -rf /usr/local/bin/pod 执行gem list | grep cocoapods 查看所有与cocoapods相 ...
- DLL程序的创建步骤和測试程序
首先,创建DLL程序 然后,加入一个导出类 比如: //Test.h #pragma once class AFX_EXT_CLASS Test { public: Test(void); ~Te ...
- 最近新出的C++右值引用的意思
看了一下这种方法的介绍,个人感觉,右值引用,更像人类的思想了,有些将编译前与编译后结合紧密的感觉. 左值引用是变量名的别名,右值引用是值的别名,也就是不将值赋给一个变量名所在的地址,直接将值所在的初始 ...
- win32 api 文件操作!
CreateFile打开文件要对文件进行读写等操作,首先必须获得文件句柄,通过该函数可以获得文件句柄,该函数是通向文件世界的大门. ReadFile从文件中读取字节信息.在打开文件获得了文件句柄之后, ...
- Note | javascript权威指南[第六版] 第2章:词法结构
语法结构规定了诸如变量名是什么样的.怎么写注释,以及程序语句之间如何分隔等规则.本章用很短的篇幅来介绍JavaScript的词法结构. 2.1.字符集 JavaScript程序是用Unic ...
- linux的文本管道连接处理技巧
举例1: strace -f -e open cpp Hello.cpp -o /dev/null 2>&1 | grep -v ENOENT | awk '{print $3}' 1) ...
- Android(java)学习笔记238:多媒体之图片画画板案例
1.首先我们编写布局文件activity_main.xml如下: <RelativeLayout xmlns:android="http://schemas.android.com/a ...