Chinaunix首页 | 论坛 | 博客
  • 博客访问: 641782
  • 博文数量: 227
  • 博客积分: 8017
  • 博客等级: 中将
  • 技术积分: 2069
  • 用 户 组: 普通用户
  • 注册时间: 2007-12-08 22:50
文章分类

全部博文(227)

文章存档

2011年(10)

2010年(55)

2009年(28)

2008年(134)

我的朋友

分类:

2009-06-17 10:54:52

这个是以前写的东西,发出来吧
1. 线程的同步和互斥
 

/*Compile: gcc -o thread thread.c -lpthread -Wall*/

#include <unistd.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <sys/mman.h>
#include <time.h>
#include <pthread.h>

//#define BSIZE 100

#define CONSUMER 10
#define PRODUCER 10

typedef struct{
    int buffer[100];
    int index;
    pthread_mutex_t mutex;
    pthread_cond_t ready_cond;
    pthread_cond_t empty_cond;
}shared_t;

void* producer(void *arg);
void* consumer(void *arg);
int get_one_item(shared_t* shared);
int put_one_item(shared_t* shared, int pval);



int main(void)
{
    pthread_t ctid[CONSUMER];
    pthread_t ptid[PRODUCER];
    shared_t *shared;
    int i =0;
    shared = (shared_t *) malloc(sizeof(shared_t));
    
    pthread_mutex_init(&shared->mutex, NULL);
    pthread_cond_init(&shared->ready_cond, NULL);
    pthread_cond_init(&shared->empty_cond, NULL);
    memset(shared->buffer, 0, sizeof(shared->buffer));
    shared->index = 0;
        
    
    setbuf(stdout, NULL);

    for (i = 0; i < PRODUCER; i++)
        pthread_create(&ptid[i], NULL, producer, (void*)shared);
    
    for (i = 0; i < CONSUMER; i++)
        pthread_create(&ctid[i], NULL, consumer, (void*)shared);

    sleep(10*60);
    return 0;
}

void* producer(void *arg)
{
    srand(time(NULL));
    int pval;
    shared_t *shared = (shared_t *)arg;
    while (1){
        pval = 1 + rand() % 1000;
        printf("thread %lu put val : %d\n", pthread_self(), put_one_item(shared, pval));
        usleep(100*1000);
    }
    
}

void *consumer(void *arg)
{
    shared_t *shared = (shared_t *)arg;
    int gval;
    while(1){
        gval = get_one_item(shared);
        printf("thread %lu get val: %d\n", pthread_self(), gval);
        //usleep(200*1000);        

    }
}


int put_one_item(shared_t* shared, int pval)
{
    pthread_mutex_lock(&shared->mutex);
    while(shared->index > 99) //max index to put is 99

        pthread_cond_wait(&shared->empty_cond, &shared->mutex);
    shared->buffer[shared->index++] = pval;
    if (shared->index == 1)
        pthread_cond_signal(&shared->ready_cond);
    pthread_mutex_unlock(&shared->mutex);
    return pval;
}


int get_one_item(shared_t* shared)
{
    int gval = 0;
    pthread_mutex_lock(&shared->mutex);
    while(shared->index < 1) //min index for get is 1

        pthread_cond_wait(&shared->ready_cond, &shared->mutex);
    gval = shared->buffer[--shared->index];
    if (shared->index == 99)
        pthread_cond_signal(&shared->empty_cond);
    pthread_mutex_unlock(&shared->mutex);
    return gval;
}

2. 同步和互斥的进程实现

/* Desc  : gcc -o process process.c -Wall -lrt -g
 *         watch mapfile: od -D mapfile

 */

#include <semaphore.h>
#include <sys/types.h>
#include <unistd.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <sys/mman.h>
#include <time.h>

#define BSIZE 100

typedef struct{
    int buffer[BSIZE];
    sem_t lock;
    sem_t nready;
    sem_t nempty;
    int index; //next to put, next get is index -1

}shared_t;
//gloabl variable

shared_t shared;

int get_one_item(shared_t *ptr);
int put_one_item(shared_t *ptr, int pval);
void err_quit(char *msg);

int main (void)
{
    pid_t pid;
    int fd;
    //int n;

    shared_t *ptr;

    /*
    fd = open("mapfile", O_RDWR | O_CREAT, 0644);
    if (fd < 0)
        err_quit("open map file failed!");
    if ((n = write(fd, &shared, sizeof(shared_t))) < 0)
        err_quit("write error");
    
    ptr = mmap(NULL, sizeof(shared_t), PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
    */

    ptr = mmap(NULL, sizeof(shared_t), PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANONYMOUS, -1, 0);
    if ((int)ptr == -1)
        err_quit("mmap error");
    close(fd);

    sem_init(&ptr->lock, 1, 1); /*shared between process, init-value = 1*/
    sem_init(&ptr->nready, 1, 0);
    sem_init(&ptr->nempty, 1, BSIZE);
    setbuf(stdout, NULL);
    
    pid = fork();
    if (pid < 0)
        err_quit("fork error");
    else if (pid == 0){         /* child */
        //sleep(2);
        while (1){
            printf("first child %d get value: %d\n", getpid(), get_one_item(ptr));
            //usleep(300*1000);
        }
    }else{ /*parent*/
        int pid2 = fork();
        if (pid2 < 0)
            err_quit("fork second process error");
        else if (pid2 ==0){
            while (1){
                printf("sencond child %d get value: %d\n", getpid(), get_one_item(ptr));
            //usleep(300*1000);

            }
        }else{
            srand(time(NULL));
            int pval = 0;
            while(1){
                pval = 1+ rand() % 1000;
                printf("parent put value: %d\n", put_one_item(ptr, pval));
                usleep(300*1000);
            }
        }
    }

    return 0;
}

int get_one_item(shared_t *ptr)
{
    int rval;
    sem_wait(&ptr->nready);
    sem_wait(&ptr->lock);
    rval = ptr->buffer[--ptr->index];
    sem_post(&ptr->lock);
    sem_post(&ptr->nempty);
    return rval;
}

int put_one_item(shared_t *ptr, int pval)
{
    sem_wait(&ptr->nempty);
    sem_wait(&ptr->lock);
    ptr->buffer[ptr->index++] = pval;
    sem_post(&ptr->lock);
    sem_post(&ptr->nready);
    return pval;
}

void err_quit(char *msg)
{
    fprintf(stderr, "%s:%s\n", msg, strerror(errno));
    exit(1);
}

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