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. javaIO流小结(1)

    UTF-8的字节占多少个字节? 常用中文字符用utf-8编码占用3个字节(大约2万多字),超大字符集中要占4个字节.在内存中是2个字节,真正写到硬盘上面的是3个字节. GBK.GB2312汉字占2个字 ...

  2. mysql 查询随机一条记录

    项目中 需要查询热门帖子,查询结果是多条中一条:SQL 如下,记录下

  3. C# WinForm登录窗口代码

    Main窗体为应用程式主窗体,Login为登录窗体.均为SDI窗体.     两种实现方式如下: 1.应用程式入口放在Login窗体,在Login窗体实现登录机制,验证通过则创建Main窗体的实例,并 ...

  4. dubbo(soa分布式)与cobar(mysql分布式)

    http://www.jianshu.com/p/0dde591f21d0 (Dubbo编译不是个顺利的事) Cobar是提供关系型数据库(MySQL)分布式服务的中间件,它可以让传统的数据库得到良好 ...

  5. undo损坏故障恢复(二)ORA-01092,ORA-00604,ORA-01110

    undo 故障诊断与恢复(二) 今天是2013-09-01,目前困扰我将近一周的问题,终于解决了,我非常感谢帮助我的朋友,也非常感谢管我要钱然后替我解决问题的朋友(我没采用).这更激发了我一定要解决这 ...

  6. Meth | phpstorm invalid descendent file name

     Failed to collect files: Invalid descendent file name "codelog_ddz.\"(]))\",\').txt& ...

  7. NSIndexPath初始化

    在UITableView中经常用到这个类,但一直不知道怎么初始化,网上抄录的代码如下,果然好用 NSIndexPath *index = [NSIndexPath indexPathForRow:0 ...

  8. codevs 1281 Xn数列 (矩阵乘法)

    /* 再来个题练练手 scanf longlong 有bug....... */ #include<cstdio> #include<iostream> #include< ...

  9. NPOI从数据库中导出数据到Excel

    首先要添加NPOI.dll程序集 https://yunpan.cn/cMeSTELJSXmJJ  访问密码 8d83 把里面的程序集都添加到引用里 下面的代码是从数据库导出到Excel { //pa ...

  10. crud的意识

    CRUD说的就是增查改删C:Create 增加对应CREATE TBL ...: ADD TBL IN (...) VALUES (...)R:Retrieve查询SELECT * from TBLU ...