zoukankan      html  css  js  c++  java
  • 多线程

    前言:如果调度策略失败,那么召唤出来的线程简直就是群魔乱舞

    #include <stdio.h>
    #include <pthread.h>
    #define BUFFER_SIZE 16 // 缓冲区数量
    struct prodcons
    {
    // 缓冲区相关数据结构
    int buffer[BUFFER_SIZE]; /* 实际数据存放的数组*/
    pthread_mutex_t lock; /* 互斥体lock 用于对缓冲区的互斥操作 */
    int readpos, writepos; /* 读写指针*/
    pthread_cond_t notempty; /* 缓冲区非空的条件变量 */
    pthread_cond_t notfull; /* 缓冲区未满的条件变量 */
    };
    /* 初始化缓冲区结构 */
    void init(struct prodcons *b)
    {
    pthread_mutex_init(&b->lock, NULL);
    pthread_cond_init(&b->notempty, NULL);
    pthread_cond_init(&b->notfull, NULL);
    b->readpos = 0;
    b->writepos = 0;
    }
    /* 将产品放入缓冲区,这里是存入一个整数*/
    void put(struct prodcons *b, int data)
    {
    pthread_mutex_lock(&b->lock);
    /* 等待 缓冲区未满*/
    if ((b->writepos + 1) % BUFFER_SIZE == b->readpos)
    /* 判断缓冲区是否有空位,试想一下(15+1*)/16余0,如果此时读指针指向0

    就证明get的还没动,不能再put了,缓冲区已满了,否则的话,证明已经被取过货物

    可以继续put了。如果不懂得,自己画个图吧*/

    {
    pthread_cond_wait(&b->notfull, &b->lock);

    /* 该函数调用需要先获得互斥,防止信号已被发出,造成无休止阻塞*/


    }
    /* 写数据,并移动指针 */
    b->buffer[b->writepos] = data;
    b->writepos++;
    if (b->writepos >= BUFFER_SIZE)
    b->writepos = 0;

    /* 缓冲区只有16个位子,写到尽头当然要置0咯

    至于>=其实等效于==,但是>=使代码可读性更强*/


    /* 设置缓冲区非空的条件变量*/
    pthread_cond_signal(&b->notempty);
    pthread_mutex_unlock(&b->lock);
    }
    /* 从缓冲区中取出整数*/
    int get(struct prodcons *b)
    {
    int data;
    pthread_mutex_lock(&b->lock);
    /* 等待 缓冲区非空*/
    if (b->writepos == b->readpos)
    {

    /* 判断缓冲区是否有货可取,让读写指针相等时阻塞就能保证拿货总是滞后于入货。

    如果不懂得,自己画个图吧*/


    pthread_cond_wait(&b->notempty, &b->lock);
    }
    /* 读数据,移动读指针*/
    data = b->buffer[b->readpos];
    b->readpos++;
    if (b->readpos >= BUFFER_SIZE)
    b->readpos = 0;
    /* 设置缓冲区未满的条件变量*/
    pthread_cond_signal(&b->notfull);
    pthread_mutex_unlock(&b->lock);
    return data;
    }
    /* 测试:生产者线程将1 到100 的整数送入缓冲区,消费者线
    程从缓冲区中获取整数,两者都打印信息*/
    #define OVER ( - 1)
    struct prodcons buffer;
    void *producer(void *data)
    {
    int n;
    for (n = 1; n <= 100; n++)
    {
    put(&buffer, n);
    printf("%d --->\n", n);

    } put(&buffer, OVER);
    return NULL;
    }
    void *consumer(void *data)
    {
    int d;
    while (1)
    {
    d = get(&buffer);
    if (d == OVER)
    break;
    printf("--->%d \n", d);
    }
    return NULL;
    }
    int main(void)
    {
    pthread_t th_a, th_b;
    void *retval;
    init(&buffer);
    /* 创建生产者和消费者线程*/
    pthread_create(&th_a, NULL, producer, 0);
    pthread_create(&th_b, NULL, consumer, 0);
    /* 主线程等待两个线程结束*/
    pthread_join(th_a, &retval);
    pthread_join(th_b, &retval);
    return 0;

    }

    两次结果不一样是因为线程间竞争所致,所以才说群魔乱舞需要调度

    最后要注意的是,编译时要加上-lpthread,否则会报错

  • 相关阅读:
    Unique Binary Search Trees——LeetCode
    Binary Tree Inorder Traversal ——LeetCode
    Maximum Product Subarray——LeetCode
    Remove Linked List Elements——LeetCode
    Maximum Subarray——LeetCode
    Validate Binary Search Tree——LeetCode
    Swap Nodes in Pairs——LeetCode
    Find Minimum in Rotated Sorted Array——LeetCode
    Linked List Cycle——LeetCode
    VR AR MR
  • 原文地址:https://www.cnblogs.com/encode/p/2584341.html
Copyright © 2011-2022 走看看