信号量
* 2种类型
- 二值信号量(取值为0或1的信号量,常用于进程间的"互斥锁")
- 计数信号量(如生产者消费者问题等)
* 2个操作
- P:等待信号量>0,然后将信号量--;
- V:信号量++,如果有则唤起一个等待信号量>0的进程
数据结构semid_ds(#include<sys/sem.h>)
相关函数
使用例子
[P操作:SemP.cpp,循环 { P操作 } ]
* 2种类型
- 二值信号量(取值为0或1的信号量,常用于进程间的"互斥锁")
- 计数信号量(如生产者消费者问题等)
* 2个操作
- P:等待信号量>0,然后将信号量--;
- V:信号量++,如果有则唤起一个等待信号量>0的进程
数据结构semid_ds(#include<sys/sem.h>)
struct semid_ds {
truct ipc_perm sem_perm; /* operation permission struct */
struct sem *sem_base; /* ptr to first semaphore in set */
ushort sem_nsems; /* # of semaphores in set */
time_t sem_otime; /* last semop time */
time_t sem_ctime; /* last change time */
};
struct ipc_perm {
key_t key; /* Key supplied to semget() */
uid_t uid; /* Effective UID of owner */
gid_t gid; /* Effective GID of owner */
uid_t cuid; /* Effective UID of creator */
gid_t cgid; /* Effective GID of creator */
unsigned short mode; /* Permissions */
unsigned short seq; /* Sequence number */
};
struct sem {
ushort semval; /* semaphore text map address */
short sempid; /* pid of last operation */
ushort semncnt; /* # awaiting semval > cval */
ushort semzcnt; /* # awaiting semval = 0 */
};
相关函数
#include <sys/sem.h>
// 创建或打开一个信号量
int semget(key_t key, int num_sems, int sem_flags);
// PV操作改变信号量的值
int semop(int sem_id, struct sembuf *sem_ops, size_t num_sem_ops);
// 控制操作,如删除等
int semctl(int sem_id, int sem_num, int command, ...);
使用例子
[P操作:SemP.cpp,循环 { P操作 } ]
#include <iostream>
#include <string.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>
using namespace std;
int main()
{
key_t iKey;
int iSemId;
// Get Sem Key
const char *pSemPath = "/data/home/andyawang/code/ipc/Semaphore";
if ((iKey = ftok(pSemPath, 1)) == -1) {
cout << "Ftok Err" << endl;
return -1;
}
// 1.semget
if ((iSemId = semget(iKey, 1, IPC_CREAT|0666)) == -1) {
cout << "Semget Err" << endl;
return -1;
}
// 2.semop(P,--)
for(int i = 0; i < 5; i ++)
{
struct sembuf sSem;
sSem.sem_num = 0;
sSem.sem_op = -1;
sSem.sem_flg = 0;
if (semop(iSemId, &sSem, 1) == -1) {
cout << "Semop Err" << endl;
return -1;
}
cout << "Semop P Suc" << endl;
}
// 3.semctl
if (semctl(iSemId, 0, IPC_RMID) == -1) {
cout << "Semctl Err" << endl;
return -1;
}
return 0;
}
[V操作:SemV.cpp,进行一次V操作 ]
#include <iostream>
#include <string.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>
using namespace std;
int main()
{
key_t iKey;
int iSemId;
// Get Sem Key
const char *pSemPath = "/data/home/andyawang/code/ipc/Semaphore";
if ((iKey = ftok(pSemPath, 1)) == -1) {
cout << "Ftok Err" << endl;
return -1;
}
// 1.semget
if ((iSemId = semget(iKey, 1, IPC_CREAT|0666)) == -1) {
cout << "Semget Err" << endl;
return -1;
}
// 2.semop(V,++)
struct sembuf sSem;
sSem.sem_num = 0;
sSem.sem_op = 1;
sSem.sem_flg = 0;
if (semop(iSemId, &sSem, 1) == -1) {
cout << "Semop Err" << endl;
return -1;
}
cout << "Semop V Suc" << endl;
return 0;
}