20191323王予涵第四章学习笔记

20191323王予涵第四章学习笔记

一、知识点总结

线程

优点:

  • 创建切换速度快
  • 相应速度快
  • 适合并行计算

缺点:

  • 需要来自用户的明确同步
  • 库函数对线程不安全
  • 在单处理机OS上使用线程解决比使用顺序慢

线程操作

管理函数:

include <Pthread.h>

pthread_create(thread, attr, function, arg) :创建线程

pthread_exit(status):终止线程

pthread_cancel(thread):取消线程

pthread_attr_init(attr):初始化线程属性

pthread_attr_destory(attr):释放attr资源

pthread_equal(pthread_t t1, pthread_t t2):比较线程

操作步骤:

创建

比较

终止

连接

线程同步

互斥量:

  • 静态方法初始化互斥量:pthread_mutex_t m = PTHREAD_MUTEX_INITIALIZER
  • 动态方法初始化互斥量:pthread_mutex_init (pthread_mutex_t *m, pthread_mutexattr_t, *attr)

int pthread_mutex_lock (pthread_mutex_t *m):封锁互斥量

int pthread_mutex_unlock(pthread_mutex_t *m):解锁互斥量

int pthread_mutex_trylock(pthread_mutex_t *m):尝试封锁互斥量,若互斥量已被封锁则返回错误,该函数旨在预防死锁

int pthread_mutex_destory(pthread_mutex_t *m):关闭互斥量

封锁的互斥量只能由上锁者解锁

条件变量:

  • 静态方法初始化条件变量:pthread_cond_t m = PTHREAD_COND_INITIALIZER
  • 动态方法初始化条件变量

信号量:

数据结构:

struct semphore{
	int value;
	struct process *queue;
}

P(wait)原语和V(signal)原语:

P(struct semphore *s){
	s -> value--;
	if(s->value < 0)
		BLOCK(S);
}

V(struct semphore *s){
	s -> value++;
	if(s->value <= 0)
		SIGNAL(S);
}

value值为1的信号量退化为互斥量,可以用来实现前趋关系

二、实践利用条件变量实现生产-消费问题

“head.h

#ifndef HEAD_H_INCLUDED
#define HEAD_H_INCLUDED
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>

#define NBUF 5
#define N 10

void *consumer();
void *producer();
int init();

int buf[NBUF];
int head, tail;
int data;
pthread_mutex_t mutex;
pthread_cond_t empty, full;
#endif // HEAD_H_INCLUDED

main.c

#include "head.h"

int main()
{
    pthread_t pro, con;
    init();
    printf("main: creat producer and consumer threads\n");
    pthread_create(&pro, NULL, producer, NULL);
    pthread_create(&con, NULL, consumer, NULL);
    printf("main: join with threads\n");
    pthread_join(pro, NULL);
    pthread_join(con, NULL);
    printf("main finish\n");
}

init.c

#include "head.h"
int init()
{
    head = tail = data = 0;
    pthread_mutex_init(&mutex, NULL);
    pthread_cond_init(&full, NULL);
    pthread_cond_init(&empty, NULL);
}

"producer.c"

#include "head.h"
void *producer()
{
    int i;
    pthread_t me = pthread_self();
    for(i = 0; i < N; i++)
    {
        pthread_mutex_lock(&mutex);
        if(data == NBUF)
        {
            printf("producer %lu: FULL,  wait\n", me);
            pthread_cond_wait(&empty, &mutex);
        }
        buf[head++] = i + 1;
        head %= NBUF;
        data++;
        printf("producer %lu: data=%d value=%d\n", me,data, i+1);
        pthread_mutex_unlock(&mutex);
        pthread_cond_signal(&full);
    }
    printf("producer %lu : exit\n", me);
}

"consumer.c"

#include "head.h"
void *consumer()
{
    int i, c;
    pthread_t me = pthread_self();
    for(i = 0; i < N; i++)
    {
        pthread_mutex_lock(&mutex);
        if(data == 0)
        {
            printf("consumer %lu: EMPTY, wait\n", me);
            pthread_cond_wait(&full, &mutex);
        }
        c = buf[tail++];
        tail %= NBUF;
        data--;
        printf("consumer %lu: value=%d\n", me ,c);
        pthread_mutex_unlock(&mutex);
        pthread_cond_signal(&empty);
    }
    printf("consumer %lu: exit\n", me);
}

posted @ 2021-10-31 20:05  WangYuHan20191323  阅读(37)  评论(0编辑  收藏  举报