UNIX网络编程(IPC)

名词解释

名称 备注
Posix(Portable Operating System Interface of UNIX) 可移植操作系统接口
System V Unix操作系统的一个版本
pipe 管道
named pipe 有名管道
mutex(mutual exclusion) 互斥锁
condtion variable 条件变量
read-write lock 读写锁
record locking 记录上锁
message queue 消息队列
semaphore 信号量
shared memory 共享内存区
分类 IPC
Pipe 管道
有名管道
Synchronization Posix互斥锁
Posix条件变量
Posix读写锁
fcntl记录上锁
Posix IPC Posix消息队列
Posix信号量
Posix共享内存区
System V IPC System V消息队列
System V信号量
System V共享内存区

互斥锁和条件变量

互斥锁用于上锁,条件变量用于等待

pthread_cond_wait函数原子地执行以下两个动作:

  • 1、给互斥锁解锁
  • 2、把调用线程投入睡眠,直到被另一个线程调用pthread_cond_signal函数唤醒
#include "stdio.h"
#include "stdlib.h"
#include "pthread.h"

#define MAXNITEMS 1000000
#define MAXNTHREADS 100
int nitems, buff[MAXNITEMS], nsignals;

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

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

int min(int a, int b) {
    return a < b? a: b;
}

void *produce(void *arg) {
    int dosignal;
    for (;;) {
        pthread_mutex_lock(&put.mutex);
        if (put.nput >= nitems) {
            pthread_mutex_unlock(&put.mutex);
            return 0;
        }

        buff[put.nput] = put.nval;
        put.nput++;
        put.nval++;
        pthread_mutex_unlock(&put.mutex);

        dosignal = 0;
        pthread_mutex_lock(&nready.mutex);
        if (nready.nready == 0) {
            dosignal = 1;
        }
        nready.nready++;
        pthread_mutex_unlock(&nready.mutex);

        if (dosignal) {
            pthread_cond_signal(&nready.cond);
            nsignals++;
        }

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

    return 0;
}

void *consume(void *arg) {
    int i;
    for (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]);
        }
    }

    return 0;
}

int main(int argc, char **argv) {
    int i, nthreads, count[MAXNTHREADS];
    pthread_t tid_produce[MAXNTHREADS], tid_consume;
    if (argc != 3) {
        printf("usage: prodcons7 <#items> <#threads>");
        exit(1);
    }

    nitems = min(atoi(argv[1]), MAXNITEMS);
    nthreads = min(atoi(argv[2]), MAXNTHREADS);
    pthread_setconcurrency(nthreads + 1);
    for (i = 0; i < nthreads; ++i) {
        count[i] = 0;
        pthread_create(&tid_produce[i], 0, produce, &count[i]);
    }
    pthread_create(&tid_consume, 0, consume, 0);

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

    exit(0);
}

猜你喜欢

转载自blog.csdn.net/hz5034/article/details/79797538