消息队列,信号量,内存共享,这几个都是一样的原理。,只不过信号量分为有名与无名
无名使用 <semaphore.h>,
有名信号量<sys/sem.h>
无名信号量不能用进程间通信,
//无名与有名的区别,有名需要KEY值与IPC标识
所以sem_init的第二个参数必须为0,,,,
(1)Posix标准中有有名信号灯和无名信号灯之分,对于有名信号灯,可以用sem_open来创建,其prototype是:sem_t *sem_open(const char *name, int oflag)//打开已有的信号灯
sem_t *sem_open(const char *name, int oflag, mode_t mode, unsigned value)//一般是创建信号灯。
期中name是信号灯的名字, oflag是0, O_CREAT 或者 O_CREAT | O_EXCL, 如果指定O_CREAT, 那么mode和value对应创建该信号的模式和初始值。 如果指定了O_EXCL, 而且该信号灯已经在系统中存在,那调用会出错返回SEM_FAILED常量。 对于Linux内核来说,有名信号灯是很晚才加入内核中的,创建或是打开有名信号时候,应该指定”/semname“名字,对应的信号灯创建在/dev/shm目录下,名字是/dev/shm/sem.semname. BTW, 用gcc/g++编译实用信号灯功能的程序时候,应该引用librt库,(e.g., g++ -lrt sem.cpp). 关闭已打开的信号灯,用sem_close(sem_t *sem). 关闭信号灯并不意味着系统会删除它,要删除一个信号灯,需要调用sem_unlink(sem_t *sem)。 有名信号灯一般是为了进程之间同步实用的。 无名信号灯,一般是为一个进程内的不同线程之间同步使用的。 创建无名信号灯的方法如下:
sem_t sem
sem_init(&sem, int shared, unsigned int value)//初始化信号灯。
......
sem_destroy(&sem)//清除信号灯。
(2)信号灯的使用和状态。
信号灯一般用来描述不同线程所共享的公共资源的数量,每一个信号灯都有一个叫做信号量的非负整数与之相连;信号量一般代表公共资源的数目,比如空闲列表中的缓冲区数目,视频中读入帧的数目,等等。对于一个线程可以用sem_wait, sem_post函数来改变一个信号灯的信号量。
sem_wait(sem_t &sem)
sem_wait的语义如下:
{
while(信号量==0)
等待; //此处线程被挂起,等待其他线程调用sem_post唤醒之。
信号量减1;
}
注意:测试信号量是否为零,和减一的操作是原子的,也就是说期间不会发生线程切换。
与sem_wait对应的调用是sem_post,语义如下:
{
信号量加1;
唤醒等待该信号量的线程;//调用sem_wait并等待的线程。
}
该操作也是原子的。
信号灯的状态可以用sem_getvalue来查看。一般来说sem_wait和sem_post的调用不必在同一个线程内成对出现(象mutex那样,lock/unlock要配对出现)。 一般的情形是这样的,一个线程等待资源可用,调用sem_wait, 另外一个线程生成资源,然后调用sem_post,唤醒等待该资源的线程。因为信号灯所描述的是线程间公共资源,使用的时候一般和mutex一起使用,mutex保证访问公共资源的线程排他性,信号灯表示资源的可用性。
欢迎分享,转载请注明来源:夏雨云
评论列表(0条)