互斥锁,条件变量,读写锁,信号灯,共享内存的一些代码






//2010-01-19 yaojianming 摘自unix网络编程2卷

//以下为多生产者,单消费者的互斥锁,条件变量的实现

#include <stdio.h>
#include <unistd.h>
#include <pthread.h>

#define MAXNITEMS 100000
#define MAXNTHREADS 10

int nitems = MAXNITEMS;
int buff[MAXNITEMS];

struct val {
    pthread_mutex_t mutex;
    int nput;
    int nval;
} put = {
    PTHREAD_MUTEX_INITIALIZER, 0, 0
};

struct mutex_cond {
    pthread_mutex_t mutex;
    pthread_cond_t cond;
    int nready;
} nready = {
    PTHREAD_MUTEX_INITIALIZER, PTHREAD_COND_INITIALIZER, 0
};

void* produce(void* arg)
{
    while(1) {
        pthread_mutex_lock(&put.mutex);
        if (put.nput >= nitems) {
            pthread_mutex_unlock(&put.mutex);
            return NULL;
        }
        buff[put.nput] = put.nval;
        put.nput++;
        put.nval++;
        pthread_mutex_unlock(&put.mutex);

        int dosignal;
        pthread_mutex_lock(&nready.mutex);
        dosignal = (nready.nready == 0);
        nready.nready++;
        pthread_mutex_unlock(&nready.mutex);

        if (dosignal)
            pthread_cond_signal(&nready.cond);

        *((int*)arg) += 1;
    }
}

void* consume(void* arg)
{
    for(int i=0; i<nitems; ++i) {
        pthread_mutex_lock(&nready.mutex);
        while(nready.nready == 0)
            pthread_cond_wait(&nready.cond, &nready.mutex);
        nready.nready--;
        pthread_mutex_unlock(&nready.mutex);

        if(buff[i] != i)
            printf("buff[%d] = %d\n", i, buff[i]);
    }
}

int main()
{
    int nthreads = MAXNTHREADS;
    int count[MAXNTHREADS];
    pthread_t tid_produce[MAXNTHREADS];
    pthread_t tid_consume;

    for(int i=0; i<nthreads; ++i) {
        count[i] = 0;
        pthread_create(&tid_produce[i], NULL, produce, &count[i]);
    }
    pthread_create(&tid_consume, NULL, consume, NULL);

    for(int i=0; i<nthreads; ++i) {
        pthread_join(tid_produce[i], NULL);
        printf("count[%d] = %d\n", i, count[i]);
    }
    printf("produce success\n");
    pthread_join(tid_consume, NULL);
    printf("consume success\n");

    return 0;
}


//2010-01-21 yaojianming 摘自unix网络编程2卷

//多个读者和多个写者的进程间通讯,采用读写锁

#include <stdio.h>
#include <unistd.h>
#include <pthread.h>
#include <stdio.h>
#include <unistd.h>
#include <pthread.h>

#define READERS 100
#define WRITERS 10

struct val {
    pthread_rwlock_t rwlock;
    int nval;
} put = {
    PTHREAD_RWLOCK_INITIALIZER, 0
};

void* thread_read(void* arg)
{
    int n = (*(int*)arg);
    pthread_rwlock_rdlock(&put.rwlock);
    printf("%d:---%d\n", n, put.nval); 
    pthread_rwlock_unlock(&put.rwlock);
} 

void* thread_write(void* arg)
{
    int n = (*(int*)arg);
    pthread_rwlock_wrlock(&put.rwlock);
    put.nval++;
    pthread_rwlock_unlock(&put.rwlock);
} 

int main()
{
    int count_read[READERS];
    int count_write[WRITERS];
    pthread_t tid_read[READERS];
    pthread_t tid_write[WRITERS];

    for(int i=0; i<READERS; ++i) {
        count_read[i] = i;
        pthread_create(&tid_read[i], NULL, thread_read, &count_read[i]);
    }
    for(int i=0; i<WRITERS; ++i) {
        count_write[i] = i;
        pthread_create(&tid_write[i], NULL, thread_write, &count_write[i]);
    }

    for(int i=0; i<READERS; ++i) {
        pthread_join(tid_read[i], NULL);
    }
    for(int i=0; i<WRITERS; ++i) {
        pthread_join(tid_write[i], NULL);
    }

    return 0;
}


//2010-01-26 yaojianming 摘自unix网络编程2卷

//单生产者,单消费者的posix信号灯的实现

#include <stdio.h>
#include <pthread.h>
#include <semaphore.h>

#define NBUFF 10
#define NITEMS 100

struct val {
    int buff[NBUFF];
    sem_t mutex,nempty,nstored;
} shared;

int nitems = NITEMS;

void* produce(void* arg)
{
    for(int i=0; i<nitems; ++i) {
        sem_wait(&shared.nempty);
        sem_wait(&shared.mutex);
        printf("producen\n");
        shared.buff[i%NBUFF] = i;
        sem_post(&shared.mutex);
        sem_post(&shared.nstored);
    }
}

void* consume(void* arg)
{
    for(int i=0; i<nitems; ++i) {
        sem_wait(&shared.nstored);
        sem_wait(&shared.mutex);
        printf("consume\n");
        if (shared.buff[i%NBUFF] != i) {
            printf("buff[%d] = %d\n", i, shared.buff[i%NBUFF]);
        }
        sem_post(&shared.mutex);
        sem_post(&shared.nempty);
    }
}

int main()
{
    pthread_t tid_produce;
    pthread_t tid_consume;

    sem_init(&shared.mutex, 0, 1);
    sem_init(&shared.nempty, 0, NBUFF);
    sem_init(&shared.nstored, 0, 0);

    pthread_create(&tid_produce, NULL, produce, NULL);
    pthread_create(&tid_consume, NULL, consume, NULL);

    pthread_join(tid_produce, NULL);
    pthread_join(tid_produce, NULL);

    sem_destroy(&shared.mutex);
    sem_destroy(&shared.nempty);
    sem_destroy(&shared.nstored);

    return 0;
}


//2010-01-26 yaojianming 摘自unix网络编程2卷

//多生产者,单消费者的posix信号灯的实现

#include <stdio.h>
#include <pthread.h>
#include <semaphore.h>

#define NBUFF 10
#define NITEMS 10000
#define MAXTHREADS 5

struct val {
    int buff[NBUFF];
    sem_t mutex,nempty,nstored;
    int nput;
    int nval;
} shared;

int nitems = NITEMS;

void* produce(void* arg)
{
    while(1) {
        sem_wait(&shared.nempty);
        sem_wait(&shared.mutex);
        if (shared.nput >= nitems) {
            sem_post(&shared.mutex);
            sem_post(&shared.nempty);
            return NULL;
        }
        shared.buff[shared.nput % NBUFF] = shared.nval;
        ++shared.nput;
        ++shared.nval;
        sem_post(&shared.mutex);
        sem_post(&shared.nstored);
        *((int*)arg) += 1;
    }
}

void* consume(void* arg)
{
    for(int i=0; i<nitems; ++i) {
        sem_wait(&shared.nstored);
        sem_wait(&shared.mutex);
        if (shared.buff[i%NBUFF] != i)
            printf("buff[%d] = %d\n", i, shared.buff[i%NBUFF]);
        sem_post(&shared.mutex);
        sem_post(&shared.nempty);
    }
}

int main()
{
    int count[MAXTHREADS];
    pthread_t tid_produce[MAXTHREADS];
    pthread_t tid_consume;

    sem_init(&shared.mutex, 0, 1);
    sem_init(&shared.nempty, 0, NBUFF);
    sem_init(&shared.nstored, 0, 0);

    for(int i=0; i<MAXTHREADS; ++i) {
        count[i] = 0;
        pthread_create(&tid_produce[i], NULL, produce, &count[i]);
    }
    pthread_create(&tid_consume, NULL, consume, NULL);

    for(int i=0; i<MAXTHREADS; ++i) {
        pthread_join(tid_produce[i], NULL);
        printf("produce[%d] = %d\n", i, count[i]);
    }
    pthread_join(tid_consume, NULL);

    sem_destroy(&shared.mutex);
    sem_destroy(&shared.nempty);
    sem_destroy(&shared.nstored);

    return 0;
}


//2010-01-26 yaojianming 摘自unix网络编程2卷

//多生产者,多消费者的posix信号灯的实现

#include <stdio.h>
#include <semaphore.h>
#include <pthread.h>

#define NBUFF 10

int nitems = 10000;
int nproduce = 15;
int nconsume = 15;

struct val {
    int buff[NBUFF];
    int nput;
    int nputval;
    int nget;
    int ngetval;
    sem_t mutex, nempty, nstored;
} shared;


void* produce(void* arg)
{
    while(1) {
        sem_wait(&shared.nempty);
        sem_wait(&shared.mutex);
        if (shared.nput >= nitems) {
            sem_post(&shared.nstored);
            sem_post(&shared.mutex);
            sem_post(&shared.nempty);
            return NULL;
        }
        shared.buff[shared.nput % NBUFF] = shared.nputval;
        shared.nput++;
        shared.nputval++;
        sem_post(&shared.mutex);
        sem_post(&shared.nstored);
        *((int*)arg) += 1;
    }
}

void* consume(void* arg)
{
    while(1) {
        sem_wait(&shared.nstored);
        sem_wait(&shared.mutex);
        if (shared.nget >= nitems) {
            sem_post(&shared.mutex);
            sem_post(&shared.nstored);
            return NULL;
        }
        int i = shared.nget % NBUFF;
        if (shared.buff[i] != shared.ngetval)
            printf("error buff[%d] = %d\n", i, shared.buff[i]);
        shared.nget++;
        shared.ngetval++;
        sem_post(&shared.mutex);
        sem_post(&shared.nempty);
        *((int*)arg) += 1;
    }
}

int main()
{
    int prodcount[30], conscount[30];
    pthread_t tid_produce[30], tid_consume[30];

    sem_init(&shared.mutex, 0, 1);
    sem_init(&shared.nempty, 0, NBUFF);
    sem_init(&shared.nstored, 0, 0);

    for(int i=0; i<nproduce; ++i) {
        prodcount[i] = 0;
        pthread_create(&tid_produce[i], NULL, produce, &prodcount[i]);
    }
    for(int i=0; i<nconsume; ++i) {
        conscount[i] = 0;
        pthread_create(&tid_consume[i], NULL, consume, &conscount[i]);
    }
    for(int i=0; i<nproduce; ++i) {
        pthread_join(tid_produce[i], NULL);
        printf("producer count[%d] = %d\n", i, prodcount[i]);
    }
    for(int i=0; i<nconsume; ++i) {
        pthread_join(tid_consume[i], NULL);
        printf("consume count[%d] = %d\n", i, conscount[i]);
    }

    sem_destroy(&shared.mutex);
    sem_destroy(&shared.nempty);
    sem_destroy(&shared.nstored);

    return 0;
}


//http://blog.csdn.net/KataDoc360/archive/2008/11/21/3348023.aspx

//进程间共享内存和信号灯同时使用


//share.h

#define sem_key 2010
#define shm_key 2011
#define SEM_PERM 0600
#define SHM_PERM 0600

struct content {
        int nput;
        int nval;
};

//client.cpp

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

#include "share.h"

void lock_sem()
{
        struct sembuf ops[2];
        ops[0].sem_num = 0;
        ops[0].sem_op = 0;
        ops[0].sem_flg = 0;
        ops[1].sem_num = 0;
        ops[1].sem_op = 1;
        ops[1].sem_flg = SEM_UNDO;

        int nsemid = semget(sem_key, 1, SEM_PERM|IPC_CREAT);
        if (nsemid < 0) {
                perror("semget");
        }
        int nret = semop(nsemid, &ops[0], 2);
        if (nret < 0) {
                perror("semop");
        }
}

void unlock_sem()
{
        struct sembuf ops[1];
        ops[0].sem_num = 0;
        ops[0].sem_op = -1;
        ops[0].sem_flg = SEM_UNDO|IPC_NOWAIT;

        int nsemid = semget(sem_key, 1, SEM_PERM|IPC_CREAT);
        if (nsemid < 0) {
                perror("semget");
        }
        int nret = semop(nsemid, &ops[0], 1);
        if (nret < 0) {
                perror("semop");
        }
}

int main()
{
        int nshmid = shmget(shm_key, sizeof(content), SHM_PERM|IPC_CREAT);
        if (nshmid < 0) {
                perror("shmget");
        }

        struct content* p = (content*)shmat(nshmid, NULL, 0);
        lock_sem();
        p->nput++;
        p->nval++;
        unlock_sem();

        return 0;
}

//server.cpp

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

#include "share.h"

void lock_sem()
{
        struct sembuf ops[2];
        ops[0].sem_num = 0;
        ops[0].sem_op = 0;
        ops[0].sem_flg = 0;
        ops[1].sem_num = 0;
        ops[1].sem_op = 1;
        ops[1].sem_flg = SEM_UNDO;

        int nsemid = semget(sem_key, 1, SEM_PERM|IPC_CREAT);
        if (nsemid < 0) {
                perror("semget");
        }
        int nret = semop(nsemid, &ops[0], 2);
        if (nret < 0) {
                perror("semop");
        }
}

void unlock_sem()
{
        struct sembuf ops[1];
        ops[0].sem_num = 0;
        ops[0].sem_op = -1;
        ops[0].sem_flg = SEM_UNDO|IPC_NOWAIT;

        int nsemid = semget(sem_key, 1, SEM_PERM|IPC_CREAT);
        if (nsemid < 0) {
                perror("semget");
        }
        int nret = semop(nsemid, &ops[0], 1);
        if (nret < 0) {
                perror("semop");
        }
}

void delete_sem()
{
        int nsemid = semget(sem_key, 1, SEM_PERM|IPC_CREAT);
        if (nsemid < 0) {
                perror("semget");
        }

        semctl(nsemid, 0, IPC_RMID);
}

int main()
{
        int nshmid = shmget(shm_key, sizeof(content), SHM_PERM|IPC_CREAT);
        if (nshmid < 0) {
                perror("shmget");
        }

        struct content *= (content*)shmat(nshmid, NULL, 0);
        lock_sem();
        printf("nput:%d = %d\n", p->nput, p->nval);
        unlock_sem();

        shmctl(nshmid, IPC_RMID, 0);
        delete_sem();

        return 0;
}


from:http://blog.chinaunix.net/uid-14348211-id-2821145.html


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值