进程互斥代码

模拟生产者-消费者的示例程序:

#include <sys/types.h>

#include <unistd.h>

#include <signal.h>

#include <stdio.h>

#include <string.h>

#include <sys/ipc.h>

#include <sys/shm.h>

#include <sys/sem.h>

#define MY_SHMKEY 10071500 // need to change

#define MY_SEMKEY 10071500 // need to change

void sigend(int);

int shmid, semid;

int main(void)

{

    int *shmptr, semval, local;

    struct sembuf semopbuf;

    if((shmid=shmget(MY_SHMKEY, sizeof(int), IPC_CREAT|IPC_EXCL|0666)) < 0)

    { /* shared memory exists, act as client */

        shmid=shmget(MY_SHMKEY, sizeof(int), 0666);

        semid=semget(MY_SEMKEY, 2, 0666);

        shmptr=(int *)shmat(shmid, 0, 0);

        printf("Act as producer. To end, input 0 when prompted.\n\n");

printf("Input a number:\n");

scanf("%d", &local);

        while( local )

{

    semopbuf.sem_num=0;

    semopbuf.sem_op=-1;

    semopbuf.sem_flg=SEM_UNDO;

    semop(semid, &semopbuf, 1); /* P(S1) */

    *shmptr = local;

    semopbuf.sem_num=1;

    semopbuf.sem_op=1;

    semopbuf.sem_flg=SEM_UNDO;

    semop(semid, &semopbuf, 1); /* V(S2) */

    printf("Input a number:\n");

    scanf("%d", &local);

        }

    }

    else /* acts as server */

    {

        semid=semget(MY_SEMKEY, 2, IPC_CREAT|0666);

        shmptr=(int *)shmat(shmid, 0, 0);

semval=1;

semctl(semid, 0, SETVAL, semval); /* set S1=1 */

semval=0;

semctl(semid, 1, SETVAL, semval); /* set S2=0 */

        signal(SIGINT, sigend);

        signal(SIGTERM, sigend);

        printf("ACT CONSUMER!!! To end, try Ctrl+C or use kill.\n\n");

        while(1)

        {

    semopbuf.sem_num=1;

    semopbuf.sem_op=-1;

    semopbuf.sem_flg=SEM_UNDO;

    semop(semid, &semopbuf, 1); /* P(S2) */

            printf("Shared memory set to %d\n", *shmptr);

    semopbuf.sem_num=0;

    semopbuf.sem_op=1;

    semopbuf.sem_flg=SEM_UNDO;

    semop(semid, &semopbuf, 1); /* V(S1) */

        }

    }

}

void sigend(int sig)

{

    shmctl(shmid, IPC_RMID, 0);

    semctl(semid, IPC_RMID, 0);

    exit(0);

}

模拟临界资源访问的示例程序:

#include <sys/types.h>

#include <unistd.h>

#include <signal.h>

#include <stdio.h>

#include <string.h>

#include <sys/ipc.h>

#include <sys/shm.h>

#define MY_SHMKEY 10071800 // need to change

#define MAX_BLOCK 1024

#define MAX_CMD 8

struct shmbuf {

    int top;

    int stack[MAX_BLOCK];

} *shmptr, local;

char cmdbuf[MAX_CMD];

int shmid, semid;

void sigend(int);

void relblock(void);

int  getblock(void);

void showhelp(void);

void showlist(void);

void getcmdline(void);

int main(void)

{

    if((shmid=shmget(MY_SHMKEY, sizeof(struct shmbuf), IPC_CREAT|IPC_EXCL|0666)) < 0)

    { /* shared memory exists, act as client */

        shmid=shmget(MY_SHMKEY, sizeof(struct shmbuf), 0666);

        shmptr=(struct shmbuf *)shmat(shmid, 0, 0);

local.top=-1;

showhelp();

getcmdline();

        while(strcmp(cmdbuf,"end\n"))

{

    if(!strcmp(cmdbuf,"get\n"))

getblock();

    else if(!strcmp(cmdbuf,"rel\n"))

relblock();

    else if(!strcmp(cmdbuf,"list\n"))

showlist();

    else if(!strcmp(cmdbuf,"help\n"))

showhelp();

    getcmdline();

        }

    }

    else /* acts as server */

    {

int i;

        shmptr=(struct shmbuf *)shmat(shmid, 0, 0);

        signal(SIGINT, sigend);

        signal(SIGTERM, sigend);

        printf("NO OTHER OPERATION but press Ctrl+C or use kill to end.\n");

shmptr->top=MAX_BLOCK-1;

for(i=0; i<MAX_BLOCK; i++)

    shmptr->stack[i]=MAX_BLOCK-i;

        sleep(1000000); /* cause sleep forever. */

    }

}

void sigend(int sig)

{

    shmctl(shmid, IPC_RMID, 0);

    semctl(semid, IPC_RMID, 0);

    exit(0);

}

void relblock(void)

{

    if(local.top<0)

    {

printf("No block to release!");

return;

    }

    shmptr->top++;

    shmptr->stack[shmptr->top]=local.stack[local.top--];

}

int  getblock(void)

{

    if(shmptr->top<0)

    {

printf("No free block to get!");

return;

    }

    local.stack[++local.top]=shmptr->stack[shmptr->top];

    shmptr->top--;

}

void showhelp(void)

{

    printf("\navailable COMMAND:\n\n");

    printf("help\tlist this help\n");

    printf("list\tlist all gotten block number\n");

    printf("get\tget a new block\n");

    printf("rel\trelease the last gotten block\n");

    printf("end\texit this program\n");

}

void showlist(void)

{

    int i;

    printf("List all gotten block number:\n");

    for(i=0; i<=local.top; i++)

printf("%d\t", local.stack[i]);

}

void getcmdline(void)

{

    printf("\n?> ");

    fgets(cmdbuf, MAX_CMD-1, stdin);

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值