uc笔记12---竞争与同步,互斥量,信号量,死锁,条件变量,哲学家就餐问题

本文详细介绍了Linux线程同步中的核心概念,包括竞争与同步问题、互斥量的使用、信号量机制、死锁问题以及条件变量的实现。通过示例代码展示了如何利用这些同步原语解决并发问题,如哲学家就餐问题。通过理解这些概念,读者可以更好地理解和解决多线程环境中的同步问题。
摘要由CSDN通过智能技术生成
1.    竞争与同步
    当多个线程同时访问其所共享的进程资源时,需要相互协调,以防止出现数据不一致、不完整的问题;这就叫线程同步。

    范例:vie.c
        #include <stdio.h>
        #include <string.h>
        #include <pthread.h>
        unsigned int g_cn = 0;
        void* thread_proc (void* arg) {
            unsigned int i;
            for (i = 0; i < 100000000; i++)
                ++g_cn;
            return NULL;
        }
        int main (void) {
            size_t i;
            pthread_t tids[2];
            int error;
            for (i = 0; i < sizeof (tids) / sizeof (tids[0]); i++)
                if ((error = pthread_create (&tids[i], NULL, thread_proc, NULL)) != 0) {
                    fprintf (stderr, "pthread_create: %s\n", strerror (error));
                    return -1;
                }
            for (i = 0; i < sizeof (tids) / sizeof (tids[0]); i++)
                if ((error = pthread_join (tids[i], NULL)) != 0) {
                    fprintf (stderr, "pthread_join: %s\n", strerror (error));
                    return -1;
                }
            printf ("g_cn = %u\n", g_cn);
            return 0;
        }
    运行结果并不是 200000000,原因如下:

    理想中的原子++:
    ----------------------+---------------------+------
                线程1        |            线程2        |    内存
    -----------+----------+----------+----------+------
        指  令    |    寄存器    |    指  令    |    寄存器    |    g_cn
    -----------+----------+----------+----------+------
        读内存    |    0        |            |            |    0
        算加法    |    1        |            |            |    0
        写内存    |    1        |            |            |    1
                |            |    读内存    |    1        |    1
                |            |    算加法    |    2        |    2
                |            |    写内存    |    2        |    2
    -----------+----------+----------+----------+------

    现实中的非原子++:
    ----------------------+---------------------+------
                线程1        |            线程2        |    内存
    -----------+----------+----------+----------+------
        指  令    |    寄存器    |    指  令    |    寄存器    |    g_cn
    -----------+----------+----------+----------+------
        读内存    |    0        |            |            |    0
                |            |    读内存    |    0        |    0
        算加法    |    1        |            |            |    0
                |            |    算加法    |    1        |    0
        写内存    |    1        |            |            |    1
                |            |    写内存    |    1        |    1
    -----------+----------+----------+----------+------

2.    互斥量

    int pthread_mutex_init (pthread_mutex_t* mutex, const pthread_mutexattr_t* mutexattr);

    亦可表示为:

    pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;

    int pthread_mutex_lock (pthread_mutex_t* mutex);

    int pthread_mutex_unlock (pthread_mutex_t* mutex);

    int pthread_mutex_destroy (pthread_mutex_t* mutex);

    1) 互斥量被初始化为非锁定状态;
    2) 线程 1 调用 pthread_mutex_lock 函数,立即返回,互斥量呈锁定状态;
    3) 线程 2 调用 pthread_mutex_lock 函数,阻塞等待;
    4) 线程 1 调用 pthread_mutex_unlock 函数,互斥量呈非锁定状态;
    5) 线程 2 被唤醒,从 pthread_mutex_lock 函数中返回,互斥量呈锁定状态;
    . . .

    范例:mutex.c
        #include <stdio.h>
        #include <string.h>
        #include <pthread.h>
        unsigned int g_cn = 0;
        /* 用这条语句可以替代下面的 pthread_mutex_init 和 ptread_mutex_destroy;
        pthread_mutex_t g_mutex = PTHREAD_MUTEX_INITIALIZER;
        */
        pthread_mutex_t g_mtx;
        void* thread_proc (void* arg) {
            unsigned int i;
            for (i = 0; i < 100000000; i++) {
                pthread_mutex_lock (&g_mtx);
                ++g_cn;
                pthread_mutex_unlock (&g_mtx);
            }
            return NULL;
        }
        int main (void) {
            size_t i;
            pthread_t tids[2];
            int error;
            pthread_mutex_init (&g_mtx, NULL);
            for (i = 0; i < sizeof (tids) / sizeof (tids[0]); i++)
                if ((error = pthread_create (&tids[i], NULL, thread_proc, NULL)) != 0) {
                    fprintf (stderr, "pthread_create: %s\n", strerror (error));
                    return -1;
                }
            for (i = 0; i < sizeof (tids) / sizeof (tids[0]); i++)
                if ((err
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值