企业网站建设方案 word,有没有给别人做图赚钱的网站,做网站的基本步骤,手机网站管理信号量 信号量(semaphore) 与已经介绍过的 IPC 结构不同#xff0c;它是一个计数器#xff0c;信号量用于实现进程间的与斥与同步#xff0c;而不是用于存储进程间通信数据。 1、特点 #xff08;1#xff09;信号量用于进程间同步#xff0c;若要在进程间传递数据需要结…信号量 信号量(semaphore) 与已经介绍过的 IPC 结构不同它是一个计数器信号量用于实现进程间的与斥与同步而不是用于存储进程间通信数据。 1、特点 1信号量用于进程间同步若要在进程间传递数据需要结合共享内存 2信号量基于操作系统的 PV 操作程序对信号量的操作都是原了操作。 3每次对信号量的 PV 操作不仅限于对信号量值加 1 或减 1而且可以加减任意正整数 4支持信号量组 2、原型 最简单的信号量是只能取 0和 1 的变量这也是信号量最常见的一种形式叫做二值信号量Binary Semaphore) 。而可以取多个正整数的信号量被称为通用信号量。 Linux 下的信号量函数都是在通用的信号量数组上进行操作而不是在一个单一的二值信号量上进行操作。
头文件 1 #include sys/sem.h 2 // 创建或获取一个信号量组: 若成功返回信号量集ID失败返回-1
3 int semget(key_t key, int nsems, int semflg);
4 // 对信号量组进行操作改变信号量的值: 成功返回0失败返回-1
5 int semop(int semid, struct sembuf *sops, unsigned nsops); 6 // 控制信号量的相关信息 7 int semctl(int semid, int semnum, int cmd, ...);
PV操作P可看作拿锁V看作放回锁
PV操作的含义PV操作由P操作原语和V操作原语组成原语是不可中断的过程对信号量进行操作具体定义如下 PS①将信号量S的值减1即SS-1 ②如果S0则该进程继续执行否则该进程置为等待状态排入等待队列。 VS①将信号量S的值加1即SS1 ②如果S0则该进程继续执行否则释放队列中第一个等待信号量的进程。 利用信号量和PV操作实现进程互斥的一般模型是 进程P1 进程P2 …… 进程Pn …… …… …… PS PS PS 临界区 临界区 临界区 VS VS VS …… …… …… …… 使用PV操作实现进程互斥时应该注意的是 1每个程序中用户实现互斥的P、V操作必须成对出现先做P操作进临界区后做V操作出临界区。若有多个分支要认真检查其成对性。 2P、V操作应分别紧靠临界区的头尾部临界区的代码应尽可能短不能有死循环。 3互斥信号量的初值一般为1。
临界资源临界区
多道程序系统中存在许多进程它们共享各和资源然而有很多资源一次只能供一个进程使用。一次仅允许一个进程使用的资源称为临界资源。许多物理设备都属于临界资源如输入机、打印机、磁带机等。
示例fork一个进程不知道父进程还是子进程先运行都有可能那么我们可以通过信号量与PV操作来控制让子进程先运行 编译结果 代码可复制
#include stdio.h #include sys/types.h #include sys/ipc.h #include sys/sem.h //int semget(key_t key, int nsems, int semflg); //int semctl(int semid, int semnum, int cmd, ...); //int semop(int semid, struct sembuf *sops, unsigned nsops);
union semun { int val; /* Value for SETVAL */ struct semid_ds *buf; /* Buffer for IPC_STAT, IPC_SET */ unsigned short *array; /* Array for GETALL, SETALL */ struct seminfo *__buf; /* Buffer for IPC_INFO (Linux-specific) */ };
void pGetKey(int id) { struct sembuf set; set.sem_num 0; set.sem_op -1; set.sem_flgSEM_UNDO; semop(id, set ,1); printf(getkey\n); }
void vPutBackKey(int id) { struct sembuf set; set.sem_num 0; set.sem_op 1; set.sem_flgSEM_UNDO; semop(id, set ,1); printf(put back the key\n); }
int main(int argc, char const *argv[]) { key_t key; int semid; key ftok(.,2); //信号量集合中有一个信号量 semid semget(key, 1, IPC_CREAT|0666);//获取/创建信号量 union semun initsem; initsem.val 0; //操作第0个信号量 semctl(semid, 0, SETVAL, initsem);//初始化信号量 //SETVAL设置信号量的值设置为inisem int pid fork(); if(pid 0){ //去拿锁 pGetKey(semid); printf(this is father\n); vPutBackKey(semid); //锁放回去 semctl(semid,0,IPC_RMID); } else if(pid 0){ printf(this is child\n); vPutBackKey(semid); }else{ printf(fork error\n); } return 0; }