POSIX线程同步

同步对象是内存中的变量,可以按照与访问数据完全相同的方式对其进行访问。不同进程中的线程可以通过放在由线程控制的共享内存中的同步对象互相通信。尽管不同进程中的线程通常互不可见,但这些线程仍可以互相通信。

同步对象还可以放在文件中。同步对象可以比创建它的进程具有更长的生命周期。

同步对象具有以下可用类型:

  • 互斥锁

  • 条件变量

  • 读写锁

  • 信号

同步的作用包括以下方面:

  • 同步是确保共享数据一致性的唯一方法。

  • 两个或多个进程中的线程可以合用一个同步对象。由于重新初始化同步对象会将对象的状态设置为解除锁定,因此应仅由其中的一个协作进程来初始化同步对象。

  • 同步可确保可变数据的安全性。

  • 进程可以映射文件并指示该进程中的线程获取记录锁。一旦获取了记录锁,映射此文件的任何进程中尝试获取该锁的任何线程都会被阻塞,直到释放该锁为止。

  • 访问一个基本类型变量(如整数)时,可以针对一个内存负荷使用多个存储周期。如果整数没有与总线数据宽度对齐或者大于数据宽度,则会使用多个存储周期。尽管这种整数不对齐现象不会出现在 SPARC® Platform Edition 体系结构上,但是可移植的程序却可能会出现对齐问题。

互斥锁属性

使用互斥锁(互斥)可以使线程按顺序执行。通常,互斥锁通过确保一次只有一个线程执行代码的临界段来同步多个线程。互斥锁还可以保护单线程代码。

操作

相关函数说明

初始化互斥锁属性对象 

pthread_mutexattr_init 语法

销毁互斥锁属性对象 

pthread_mutexattr_destroy 语法

设置互斥锁范围 

pthread_mutexattr_setpshared 语法

获取互斥锁范围 

pthread_mutexattr_getpshared 语法

设置互斥锁的类型属性 

pthread_mutexattr_settype 语法

获取互斥锁的类型属性 

pthread_mutexattr_gettype 语法

设置互斥锁属性的协议 

pthread_mutexattr_setprotocol 语法

获取互斥锁属性的协议 

pthread_mutexattr_getprotocol 语法

设置互斥锁属性的优先级上限 

pthread_mutexattr_setprioceiling 语法

获取互斥锁属性的优先级上限 

pthread_mutexattr_getprioceiling 语法

设置互斥锁的优先级上限 

pthread_mutex_setprioceiling 语法

获取互斥锁的优先级上限 

pthread_mutex_getprioceiling 语法

设置互斥锁的强健属性 

pthread_mutexattr_setrobust_np 语法

获取互斥锁的强健属性 

pthread_mutexattr_getrobust_np 语法

嵌套锁 示例:

typedef struct node1 {

    int value;

    struct node1 *link;

    pthread_mutex_t lock;

} node1_t;


//单链接列表和嵌套锁定
node1_t ListHead;


node1_t *delete(int value)

{

    node1_t *prev, *current;



    prev = &ListHead;

    pthread_mutex_lock(&prev->lock);

    while ((current = prev->link) != NULL) {

        pthread_mutex_lock(&current->lock);

        if (current->value == value) {

            prev->link = current->link;

            pthread_mutex_unlock(&current->lock);

            pthread_mutex_unlock(&prev->lock);

            current->link = NULL;

            return(current);

        }

        pthread_mutex_unlock(&prev->lock);

        prev = current;

    }

    pthread_mutex_unlock(&prev->lock);

    return(NULL);

}


//循环链接列表结构
typedef struct node2 {

    int value;

    struct node2 *link;

    pthread_mutex_t lock;

} node2_t;

//循环链接列表和嵌套锁定
void Hit Neighbor(node2_t *me) {

    while (1) {

        pthread_mutex_lock(&me->lock);

        if (pthread_mutex_lock(&me->link->lock)!= 0) {

            /* failed to get lock */             

            pthread_mutex_unlock(&me->lock);              

            continue;         

        }         

        break;     

    }     

    me->link->value += me->value;     

    me->value /=2;     

    pthread_mutex_unlock(&me->link->lock);     

    pthread_mutex_unlock(&me->lock);

}

条件变量属性

使用条件变量可以以原子方式阻塞线程,直到某个特定条件为真为止。条件变量始终与互斥锁一起使用

使用条件变量,线程可以以原子方式阻塞,直到满足某个条件为止。对条件的测试是在互斥锁(互斥)的保护下进行的。

如果条件为假,线程通常会基于条件变量阻塞,并以原子方式释放等待条件变化的互斥锁。如果另一个线程更改了条件,该线程可能会向相关的条件变量发出信号,从而使一个或多个等待的线程执行以下操作:

  • 唤醒

  • 再次获取互斥锁

  • 重新评估条件

在以下情况下,条件变量可用于在进程之间同步线程:

  • 线程是在可以写入的内存中分配的

  • 内存由协作进程共享

调度策略可确定唤醒阻塞线程的方式。对于缺省值 SCHED_OTHER,将按优先级顺序唤醒线程。

 

操作

函数说明

初始化条件变量属性 

pthread_condattr_init 语法

删除条件变量属性 

pthread_condattr_destroy 语法

设置条件变量的范围  

pthread_condattr_setpshared 语法

获取条件变量的范围 

pthread_condattr_getpshared 语法

原文地址:https://www.cnblogs.com/gardenofhu/p/8608778.html