linux信号量

#include <stdio.h>   
#include <sys/types.h>   
#include <sys/ipc.h>   
#include <sys/sem.h>   
  
#define SHM_KEY 0x33   
#define SEM_KEY 0x44   
  
union semun {   
    int val;   
    struct semid_ds *buf;   
    unsigned short *array;   
};   
  
int P(int semid)   
{   
    struct sembuf sb;   
    sb.sem_num = 0;   
    sb.sem_op = -1;   
    sb.sem_flg = SEM_UNDO;   
       
    if(semop(semid, &sb, 1) == -1) {   
        perror("semop");   
        return -1;   
    }   
    return 0;   
}   
  
int V(int semid)   
{   
    struct sembuf sb;   
    sb.sem_num = 0;   
    sb.sem_op = 1;   
    sb.sem_flg = SEM_UNDO;   
       
    if(semop(semid, &sb, 1) == -1) {   
        perror("semop");   
        return -1;   
    }   
    return 0;   
}   
  
int main(int argc, char **argv)   
{   
    pid_t pid;   
    int i, shmid, semid;   
    int *ptr;   
    union semun semopts;   
  
    /* 创建一块共享内存, 存一个int变量 */  
    if ((shmid = shmget(SHM_KEY, sizeof(int), IPC_CREAT | 0600)) == -1) {   
        perror("msgget");   
    }   
  
    /* 将共享内存映射到进程, fork后子进程可以继承映射 */  
    if ((ptr = (int *)shmat(shmid, NULL, 0)) == (void *)-1) {   
        perror("shmat");   
    }   
    *ptr = 0;   
  
    /* 创建一个信号量用来同步共享内存的操作 */  
    if ((semid = semget(SEM_KEY, 1, IPC_CREAT | 0600)) == -1) {   
        perror("semget");   
    }   
  
    /* 初始化信号量 */  
    semopts.val = 1;   
    if (semctl(semid, 0, SETVAL, semopts) < 0) {   
        perror("semctl");   
    }   
  
    if ((pid = fork()) < 0) {   
        perror("fork");   
    } else if (pid == 0) {      /* Child */  
        /* 子进程对共享内存加1 */  
        for (i = 0; i < 100000; i++) {   
            P(semid);   
            (*ptr)++;   
            V(semid);   
            printf("child: %d\n", *ptr);   
        }   
    } else {                    /* Parent */  
        /* 父进程对共享内存减1 */  
        for (i = 0; i < 100000; i++) {   
            P(semid);   
            (*ptr)--;   
            V(semid);   
            printf("parent: %d\n", *ptr);   
        }   
        waitpid(pid);   
        /* 如果同步成功, 共享内存的值为0 */  
        printf("finally: %d\n", *ptr);   
    }   
  
    return 0;   
}  
#include <stdio.h>   
#include <sys/types.h>   
#include <sys/ipc.h>   
#include <semaphore.h>   
#include <fcntl.h>           /* For O_* constants */   
#include <sys/stat.h>        /* For mode constants */   
#include <stdlib.h>   
  
#define SHM_KEY 0x33   
  
int main(int argc, char **argv)   
{   
    pid_t pid;   
    int i, shmid;   
    int *ptr;   
    sem_t *sem;   
  
    /* 创建一块共享内存, 存一个int变量 */  
    if ((shmid = shmget(SHM_KEY, sizeof(int), IPC_CREAT | 0600)) == -1) {   
        perror("msgget");   
    }   
  
    /* 将共享内存映射到进程, fork后子进程可以继承映射 */  
    if ((ptr = (int *)shmat(shmid, NULL, 0)) == (void *)-1) {   
        perror("shmat");   
    }   
    *ptr = 0;   
  
    /* posix的有名信号量是kernel persistent的  
     * 调用sem_unlink删除以前的信号量 */  
    sem_unlink("/mysem");   
  
    /* 创建新的信号量, 初值为1, sem_open会创建共享内存  
     * 所以信号量是内核持续的 */  
    if ((sem = sem_open("/mysem", O_CREAT, 0600, 1)) == SEM_FAILED) {   
        perror("sem_open");   
    }   
  
    if ((pid = fork()) < 0) {   
        perror("fork");   
    } else if (pid == 0) {      /* Child */  
        /* 子进程对共享内存加1 */  
        for (i = 0; i < 100000; i++) {   
            sem_wait(sem);   
            (*ptr)++;   
            sem_post(sem);   
            printf("child: %d\n", *ptr);   
        }   
    } else {                    /* Parent */  
        /* 父进程对共享内存减1 */  
        for (i = 0; i < 100000; i++) {   
            sem_wait(sem);   
            (*ptr)--;   
            sem_post(sem);   
            printf("parent: %d\n", *ptr);   
        }   
        waitpid(pid);   
        /* 如果同步成功, 共享内存的值为0 */  
        printf("finally: %d\n", *ptr);   
        sem_unlink("/mysem");   
    }   
  
    return 0;   
}  
#include <sys/types.h>  
#include <sys/sem.h>  
#include <sys/ipc.h>  
#include <string.h>  
#include <errno.h>  
#include <unistd.h>  
#include <stdio.h>  
  
int main (int argc, char **argv)  
{  
    key_t ipckey;  
    int semid;  
    /*建立两个信号灯结构*/  
    struct sembuf sem[2]; /* sembuf defined in sys/sem.h */  
    /* 创建IPC Key */  
    ipckey = ftok("/tmp/rich", 42);  
    /* 创建信号量. 4 == READ, 2 == ALTER */  
    semid = semget(ipckey, 1, 0666 | IPC_CREAT);  
    if (semid < 0)   
    {  
        printf("Error - %sn", strerror(errno));  
        _exit(1);  
    }  
    /*设置*/  
    /* These never change so leave them outside the loop */  
    sem[0].sem_num = 0;  
    sem[1].sem_num = 0;  
    sem[0].sem_flg = SEM_UNDO; /* Release semaphore on exit */  
    sem[1].sem_flg = SEM_UNDO; /* Release semaphore on exit */  
    while(1)  
    {   
        printf("[%s] Waiting for the semaphore to be releasedn\n", argv[1]);  
        /* 设置两个信号灯,灯1等待,灯2请求资源锁 */  
        sem[0].sem_op = 0; /* Wait for zero */  
        sem[1].sem_op = 1; /* Add 1 to lock it*/  
        /*设置信号量集,两个信号量*/  
        semop(semid, sem, 2);  
  
        /*资源锁区*/  
        printf("[%s] I have the semaphoren\n", argv[1]);  
        sleep(rand() % 3);   
        /* Critical section, sleep for 0-2 seconds */  
        sem[0].sem_op = -1; /* Decrement to unlock */  
        /*出锁,对信号量1操作*/  
        semop(semid, sem, 1);  
        printf("[%s] Released semaphoren\n", argv[1]);  
        sleep(rand() % 3); /* Sleep 0-2 seconds */  
    }  
}
#include "all.h"

/* 每个字符输出的间隔时间 */
#define TEN_MILLION 5000000L
#define BUFSIZE 1024

void *threadout(void *args);

int main(int argc, char *argv[]) 
{
    int error;
       int i;
       int n;
    sem_t semlock;
       pthread_t *tids;
    
       if (argc != 2) { 
           fprintf (stderr, "Usage: %s numthreads\n", argv[0]);
              return 1;
       }   
       n = atoi(argv[1]);
       tids = (pthread_t *)calloc(n, sizeof(pthread_t));
       if (tids == NULL) {
           perror("Failed to allocate memory for thread IDs");
           return 1;
       }   
       if (sem_init(&semlock, 0, 1) == -1) {
           perror("Failed to initialize semaphore");
           return 1;
       }   
       for (i = 0; i < n; i++) {
           if (error = pthread_create(tids + i, NULL, threadout, &semlock)) {
               fprintf(stderr, "Failed to create thread:%s\n", strerror(error));
                  return 1;
          }
    }
       for (i = 0; i < n; i++) {
           if (error = pthread_join(tids[i], NULL)) {
               fprintf(stderr, "Failed to join thread:%s\n", strerror(error));
                 return 1;
              }
    }
    return 0;
}

void *threadout(void *args) 
{
    char buffer[BUFSIZE];
       char *c; 
       sem_t *semlockp;
       struct timespec sleeptime;
    
       semlockp = (sem_t *)args;
       sleeptime.tv_sec = 0;
       sleeptime.tv_nsec = TEN_MILLION;
    
       snprintf(buffer, BUFSIZE, "This is thread from process %ld\n",
               (long)getpid());
       c = buffer;
       /****************** entry section *******************************/
       while (sem_wait(semlockp) == -1)
           if(errno != EINTR) {
               fprintf(stderr, "Thread failed to lock semaphore\n");
                 return NULL;
              }
       /****************** start of critical section *******************/
       while (*c != '\0') {
              fputc(*c, stderr);
              c++;
              nanosleep(&sleeptime, NULL);
       }
       /****************** exit section ********************************/
       if (sem_post(semlockp) == -1)
              fprintf(stderr, "Thread failed to unlock semaphore\n");
       /****************** remainder section ***************************/
       return NULL;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值