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 进程同步的更多相关文章

  1. 信号量进程同步,王明学learn

    信号量进程同步 一组并发进程进行互相合作.互相等待,使得各进程按一定的顺序执行的过程称为进程间的同步. 信号量在进程同步时初始值为:0 信号量在进程互斥时初始值为:大于0的 本章节主要使用信号量,使的 ...

  2. system V信号量和Posix信号量

    一.函数上的区别 信号量有两种实现:传统的System V信号量和新的POSIX信号量.它们所提供的函数很容易被区分:对于所有System V信号量函数,在它们的名字里面没有下划线.例如,应该是sem ...

  3. Linux 多线程信号量同步

    PV原子操作 P操作: 如果有可用的资源(信号量值>0),则此操作所在的进程占用一个资源(此时信号量值减1,进入临界区代码); 如果没有可用的资源(信号量值=0),则此操作所在的进程被阻塞直到系 ...

  4. [转]一个简单的Linux多线程例子 带你洞悉互斥量 信号量 条件变量编程

    一个简单的Linux多线程例子 带你洞悉互斥量 信号量 条件变量编程 希望此文能给初学多线程编程的朋友带来帮助,也希望牛人多多指出错误. 另外感谢以下链接的作者给予,给我的学习带来了很大帮助 http ...

  5. 关于Linux下进程间使用共享内存和信号量通信的时的编译问题

    今天在编译一个使用信号量实现进程同步时,出现了库函数不存在的问题.如下图 编译结果实际上是说,没include相应的头文件,或是头文件不存在(即系统不支持该库函数) 但我man shm_open是可以 ...

  6. 线程间同步之 semaphore(信号量)

    原文地址:http://www.cnblogs.com/yuqilin/archive/2011/10/16/2214429.html semaphore 可用于进程间同步也可用于同一个进程间的线程同 ...

  7. Linux多线程实践(5) --Posix信号量与互斥量解决生产者消费者问题

    Posix信号量 Posix 信号量 有名信号量 无名信号量 sem_open sem_init sem_close sem_destroy sem_unlink sem_wait sem_post ...

  8. linux POSIX 信号量介绍

    信号量一.什么是信号量信号量的使用主要是用来保护共享资源,使得资源在一个时刻只有一个进程(线程)使用.多线程可以同时运行多个线程函数完成功能,但是对于共享数据如果不加以锁定,随意改变共享数据的值会发生 ...

  9. Linux多线程--使用信号量同步线程【转】

    本文转载自:http://blog.csdn.net/ljianhui/article/details/10813469 信号量.同步这些名词在进程间通信时就已经说过,在这里它们的意思是相同的,只不过 ...

随机推荐

  1. Heavy Transportation

    题目大意: 雨果的沉重运输是快乐的,当浮空运输出现故障时候他可以扩展业务, 但他需要一个聪明的人告诉他是否真的是一种把他的客户构建了巨型钢起重机的地方需要的所有街道都可以承受重量(这句是直接有道翻译的 ...

  2. HTML embed标签使用方法和属性详解

    一.基本语法   代码如下:   embed src=url   说明:embed可以用来插入各种多媒体,格式可以是 Midi.Wav.AIFF.AU.MP3等等,Netscape及新版的IE 都支持 ...

  3. CentOS7 盒盖休眠

    https://wiki.archlinux.org/index.php/Power_management_(%E7%AE%80%E4%BD%93%E4%B8%AD%E6%96%87) CentOS ...

  4. C#快速剔除字符串中不合法的文件名或者文件路径字符

    C#快速剔除字符串中不合法的文件名 string strFileName= "文件名称";  StringBuilder rBuilder = new StringBuilder( ...

  5. Android 网络框架--Retrofit

    1.导入Jar包 compile 'com.google.code.gson:gson:2.8.0' compile 'com.squareup.retrofit2:retrofit:2.1.0' c ...

  6. Fragment 回退栈 传递参数,点击切换图片使用Fragment ListView

    Fragment回退栈  类似与Android系统为Activity维护一个任务栈,我们也可以通过Activity维护一个回退栈来保存每次Fragment事务发生的变化. 如果你将Fragment任务 ...

  7. Java并发学习之二——获取和设置线程信息

    本文是学习网络上的文章时的总结,感谢大家无私的分享. Thread类的对象中保存了一些属性信息可以帮助我们辨别每个线程.知道它的一些信息 ID:每一个线程的独特标示: Name:线程的名称: Prio ...

  8. iOS工具种之16进制颜色转为UIColor

     #define DEFAULT_VOID_COLOR [UIColor whiteColor] + (UIColor *)colorWithHexString:(NSString *)stringT ...

  9. 你好,C++(12)怎样管理多个类型同样性质同样的数据?3.6 数组

    3.6  数组 学过前面的基本数据类型之后,我们如今能够定义单个变量来表示单个的数据.比如,我们能够用int类型定义变量来表示公交车的216路:能够用float类型定义变量来表示西红柿3.5元一斤. ...

  10. iOS 短信验证码倒计时按钮的实现

    验证码倒计时按钮的应用是非常普遍的,本文介绍了IOS实现验证码倒计时功能,点击获取验证码,进入时间倒计时,感兴趣的小伙伴们可以参考一下: 实现思路: 创建按钮,添加点击方法: 用NSTimer定时器, ...