Chinaunix首页 | 论坛 | 博客
  • 博客访问: 89759
  • 博文数量: 28
  • 博客积分: 1400
  • 博客等级: 上尉
  • 技术积分: 280
  • 用 户 组: 普通用户
  • 注册时间: 2009-07-14 21:55
文章分类

全部博文(28)

文章存档

2011年(1)

2010年(13)

2009年(14)

我的朋友

分类:

2010-03-18 00:12:25


#include <sys/types.h>
#include <unistd.h>
#include <fcntl.h>
#include <stdio.h>
#include <errno.h>

static int fl_setblock(int fd);
static int fl_clrblock(int fd);
static int lock_reg(int fd, int cmd, int type, off_t off, int whence, off_t len);

int fl_setblock(int fd)
{
    long flags = fcntl(fd, F_GETFL, 0);
    return fcntl(fd, F_SETFL, flags | O_NONBLOCK);
}

int fl_clrblock(int fd)
{
    long flags = fcntl(fd, F_GETFL, 0);

    return fcntl(fd, F_SETFL, flags & (~O_NONBLOCK));
}

/* read/write block */

/* fcntl lock */

int lock_reg(int fd, int cmd, int type, off_t off, int whence, off_t len)
{
    struct flock lk = {type, whence, off, len};
// struct flock lk;

// lk.l_type = type;

// lk.l_whence = whence;

// lk.l_start = off;

// lk.l_len = len;

    return fcntl(fd, cmd, &lk);
}

#define READ_LOCK(fd, off, whence, len)\
    lock_reg(fd, F_SETLK, F_RDLCK, off, whence, len)
#define READW_LOCK(fd, off, whence, len)\
    lock_reg(fd, F_SETLKW, F_RDLCK, off, whence, len)
#define WRITE_LOCK(fd, off, whence, len)\
    lock_reg(fd, F_SETLK, F_WRLCK, off, whence, len)
#define WRITEW_LOCK(fd, off, whence, len)\
    lock_reg(fd, F_SETLKW, F_WRLCK, off, whence, len)
#define UN_LOCK(fd, off, whence, len)\
    lock_reg(fd, F_SETLK, F_UNLCK, off, whence, len)

static void lockbyte(const char* name, int fd, off_t off);
int main(int argc, char** argv)
{
    int fd;
    pid_t pid;
    if ((fd = open("tmp_XXXXX", O_WRONLY|O_CREAT, 00644)) == -1)
    {
        perror("open(path, flags, mode)");
        return -1;
    }
    if (write(fd, "cd", 2) != 2)
    {
        perror("write(fd, data, len)");
        return -1;
    }
// lockbyte("parent", fd, 0);

// lockbyte("parent", fd, 1);

    switch (fork()){
    case -1:
        perror("fork(void)");
        break;
    case 0:
        lockbyte("child", fd, 0);
        sleep(3);
        lockbyte("child", fd, 1);
            close(fd);
// exit(0);

        break;
    default:
        lockbyte("parent", fd, 1);
        lockbyte("parent", fd, 0);
    }
    close(fd);

    printf("hello world\n");
}

static void lockbyte(const char* name, int fd, off_t off)
{
    if (WRITE_LOCK(fd, off, SEEK_SET, 1) == -1)
    {
        perror("write(fd, off, whence, len)");
        return ;
    }
    printf("%s: got the lock, byte %lu\n", name, off);
}



/* 程序副本惟一 */

int main(int argc, char** argv)
{
    char path[64] = {0};
    FILE* fp;

    snprintf(path, sizeof(path), ".tmp_%s", rindex(argv[0], '/') + 1);
    printf("\033[31m%s\033[0m\n", path);
    if ((fp = fopen(path, "ab")) == NULL)
    {
        perror("fopen(path, flags)");
        return -1;
    }
    if (WRITE_LOCK(fileno(fp), 0, SEEK_SET, 0) == -1)
    {
        fprintf(stderr, "%s id running\n", rindex(argv[0], '/') + 1);
        goto reclaim;
    }
    if (ftruncate(fileno(fp), 0) == -1)
    {
        perror("ftruncate(path, len)");
        goto reclaim;
    }
    fprintf(fp, "%d\n", getpid());
    fflush(fp);
    sleep(1000);

    printf("hello world\n");
    return -1;
reclaim:
    fclose(fp);
    return -1;
}


/* share memory/semaphore */

#include <sys/types.h>
#include <sys/shm.h>
#include <sys/sem.h>
#include <sys/ipc.h>
#include <stdio.h>

int main (int argc, char **argv)
{
    /* shm */
    key_t _ipckey;
    int shmid;
    void* addr;
    int shmsize = 1024 * 1024;

    /* Generate the ipc key */
    if ((_ipckey = ftok("/tmp", 42)) == -1)
    {
        perror("ftok(path,id)");
        return -1;
    }
    if ((shmid = shmget(_ipckey, shmsize, IPC_CREAT|0600)) == -1)
    {
        perror("shmget(key, shmsize, flags)");
        return -1;
    }

    if ((addr = shmat(shmid, NULL, 0)) == (void*)-1)
    {
        perror("shmat(shmid, NULL, flags)");
        return -1;
    }
    if (shmdt(addr) == -1)
    {
        perror("shmdt(void*)");
        return -1;
    }
    sleep(3);
    if (shmctl(shmid, IPC_RMID, NULL) == -1)
    {
        perror("shmctl(shmid, IPC_RMID, NULL)");
        return -1;
    }

    return 0;

    /* sem */
    key_t ipckey;
    int semid;
    struct sembuf sem[2]; /* sembuf defined in sys/sem.h */

    /* Generate the ipc key */
    if ((ipckey = ftok("/tmp", 42)) == -1)
    {
        perror("ftok(path,id)");
        return -1;
    }

    /* Set up the semaphore set. 4 == READ, 2 == ALTER */
    if ((semid = semget(ipckey, 1, 0666 | IPC_CREAT)) == -1)
    {
        perror("semget(key, nsems, flags)");
        return -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)
    { /* loop forever */
        printf("[%s] Waiting for the semaphore to be released\n", argv[1]);
        /* Set up two semaphore operations: test/lock */
        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 semaphore\n", argv[1]);

        sleep(5); /* Critical section, sleep for 0-2 seconds */

        sem[0].sem_op = -1; /* Decrement to unlock */
        semop(semid, sem, 1);
        printf("[%s] Released semaphore\n", argv[1]);

    //    sleep(5); /* Sleep 0-2 seconds */

    }

    return 0;
}



        信号量总结
1. SysV信号量
    #include
    #include
    #include
    key_t ftok(const char *pathname, int proj_id);
    int semget(key_t key, int nsems, int semflg);
    int semop(int semid, struct sembuf *sops, unsigned nsops);
    int semtimedop(int semid, struct sembuf *sops, unsigned nsops, struct timespec *timeout);
        int semctl(int semid, int semnum, int cmd, ...);
    struct sembuf{
        unsigned short sem_num;  /* semaphore number */
        short          sem_op;   /* semaphore operation */
        short          sem_flg;  /* operation flags */
    };
sem_op = 0, 测试sem_num是否为0;为0则继续下一步,不为0则阻塞.
sem_op > 0, sem_num加锁
       < 0, sem_num解锁

[code]
/* <转载> http://www.ibm.com/developerworks/cn/aix/library/au-ipc/index.html */
#include
#include
#include
#include

int main (int argc, char **argv)
{
    key_t ipckey;
    int semid;
    struct sembuf sem[2]; /* sembuf defined in sys/sem.h */

    /* Generate the ipc key */
    if ((ipckey = ftok("/tmp", 42)) == -1)
    {
        perror("ftok(path,id)");
        return -1;
    }

    /* Set up the semaphore set. 4 == READ, 2 == ALTER */
    if ((semid = semget(ipckey, 1, 0666 | IPC_CREAT)) == -1)
    {
        perror("semget(key, nsems, flags)");
        return -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)
    { /* loop forever */
        printf("[%s] Waiting for the semaphore to be released\n", argv[1]);
        /* Set up two semaphore operations: test/lock */
        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 semaphore\n", argv[1]);

        sleep(5); /* Critical section, sleep for 0-2 seconds */

        sem[0].sem_op = -1; /* Decrement to unlock */
        semop(semid, sem, 1);
        printf("[%s] Released semaphore\n", argv[1]);
    }

    return 0;
}

2. POSIX无名信号量
    #include
    int sem_init(sem_t *sem, int pshared, unsigned int value); //sem_init 一般初始化0/1;
    int sem_wait(sem_t *sem); //sem_wait 判断value值,为0则阻塞,不为0则--value并执行临界区域
    int sem_trywait(sem_t *sem);
    int sem_timedwait(sem_t *sem, const struct timespec *abs_timeout);
    int sem_post(sem_t *sem); //sem_post ++value并唤醒其它线程

    int sem_destroy(sem_t *sem);

/* 作用: 获得指定网卡的IP
 * 参数: devname 设备名
 * 返回值: 成功返回静态IP, 失败返回NULL, 并设置errno
 */

static char* get_localip(char* devname)
{
    int _sock;
    struct ifreq ifr;

    if ((_sock = socket(AF_INET, SOCK_DGRAM, 0)) == -1)
        return NULL;
    strcpy(ifr.ifr_name, devname);
    if (ioctl(_sock, SIOCGIFADDR, &ifr) == -1)
    {
        close(_sock);
        return NULL;
    }
    close(_sock);
    return inet_ntoa(((struct sockaddr_in*)&ifr.ifr_addr)->sin_addr);
}


阅读(704) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~