首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 其他教程 > 其他相关 >

进程间通信(IPC):信号量(Se地图hore)

2013-01-28 
进程间通信(IPC):信号量(Semaphore)假定有一个信号量变量sv,P(sv):用于等待,如果sv大于0,就给它减去1,如果

进程间通信(IPC):信号量(Semaphore)

假定有一个信号量变量sv,

P(sv):用于等待,如果sv大于0,就给它减去1,如果它的值等于0,就挂起该进程的执行

V(sv):用于发送信号,如果有其他进程因等待sv而挂起,就让它恢复运行,如果没有进程因等待sv而被挂起,就给它加1


semaphore sv=1;

loop forever{

P(sv);

critical code section;

V(sv);

noncritical code section;

}


信号量函数定义如下所示:

#include<sys/sem.h>

int semctl(int sem_id, int sem_num, int command, ...);//用来直接控制信号量信息

int semget(key_t key, int num_sems, int sem_flags);//创建一个新信号量或取得一个已有信号量的键

int semop(int sem_id, struct sembuf *sem_ops, size_t num_sem_ops);//用于改变信号量的值


/* After the #includes, the function prototypes and the global variable, we come to the main function. There the semaphore is created with a call to semget, which returns the semaphore ID. If the program is the first to be called (i.e. it's called with a parameter and argc > 1), a call is made to set_semvalue to initialize the semaphore and op_char is set to X. */#include <unistd.h>#include <stdlib.h>#include <stdio.h>#include <sys/sem.h>#include "semun.h"static int set_semvalue(void);static void del_semvalue(void);static int semaphore_p(void);static int semaphore_v(void);static int sem_id;int main(int argc, char *argv[]){    int i;    int pause_time;    char op_char = 'O';    srand((unsigned int)getpid());    sem_id = semget((key_t)1234, 1, 0666 | IPC_CREAT);    if (argc > 1) {        if (!set_semvalue()) {            fprintf(stderr, "Failed to initialize semaphore\n");            exit(EXIT_FAILURE);        }        op_char = 'X';        sleep(2);    }/* Then we have a loop which enters and leaves the critical section ten times. There, we first make a call to semaphore_p which sets the semaphore to wait, as this program is about to enter the critical section. */    for(i = 0; i < 10; i++) { if (!semaphore_p()) exit(EXIT_FAILURE);        printf("%c", op_char);fflush(stdout);        pause_time = rand() % 3;        sleep(pause_time);        printf("%c", op_char);fflush(stdout);/* After the critical section, we call semaphore_v, setting the semaphore available, before going through the for loop again after a random wait. After the loop, the call to del_semvalue is made to clean up the code. */        if (!semaphore_v()) exit(EXIT_FAILURE);        pause_time = rand() % 2;        sleep(pause_time);    }    printf("\n%d - finished\n", getpid());    if (argc > 1) {        sleep(10);        del_semvalue();    }    exit(EXIT_SUCCESS);}/* The function set_semvalue initializes the semaphore using the SETVAL command in a semctl call. We need to do this before we can use the semaphore. */static int set_semvalue(void){    union semun sem_union;    sem_union.val = 1;    if (semctl(sem_id, 0, SETVAL, sem_union) == -1) return(0);    return(1);}/* The del_semvalue function has almost the same form, except the call to semctl uses the command IPC_RMID to remove the semaphore's ID. */static void del_semvalue(void){    union semun sem_union;if (semctl(sem_id, 0, IPC_RMID, sem_union) == -1)        fprintf(stderr, "Failed to delete semaphore\n");}/* semaphore_p changes the semaphore by -1 (waiting). */static int semaphore_p(void){    struct sembuf sem_b;    sem_b.sem_num = 0;    sem_b.sem_op = -1; /* P() */    sem_b.sem_flg = SEM_UNDO;    if (semop(sem_id, &sem_b, 1) == -1) {        fprintf(stderr, "semaphore_p failed\n");        return(0);    }    return(1);}/* semaphore_v is similar except for setting the sem_op part of the sembuf structure to 1, so that the semaphore becomes available. */static int semaphore_v(void){    struct sembuf sem_b;    sem_b.sem_num = 0;    sem_b.sem_op = 1; /* V() */    sem_b.sem_flg = SEM_UNDO;    if (semop(sem_id, &sem_b, 1) == -1) {        fprintf(stderr, "semaphore_v failed\n");        return(0);    }    return(1);}


热点排行