互斥锁

 #include <cstdio>

 #include <cstdlib>

 #include <unistd.h>

 #include <pthread.h>

 #include "iostream"

 using namespace std;

 pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;

 int tmp;

 void* thread(void *arg)

 {

     cout << "thread id is " << pthread_self() << endl;

     pthread_mutex_lock(&mutex);

     tmp = ;

     cout << "Now a is " << tmp << endl;

     pthread_mutex_unlock(&mutex);

     return NULL;

 }

 int main()

 {

     pthread_t id;

     cout << "main thread id is " << pthread_self() << endl;

     tmp = ;

     cout << "In main func tmp = " << tmp << endl;

     if (!pthread_create(&id, NULL, thread, NULL))

     {

         cout << "Create thread success!" << endl;

     }

     else

     {

         cout << "Create thread failed!" << endl;

     }

     pthread_join(id, NULL);

     pthread_mutex_destroy(&mutex);

     return ;

 }

 //编译:g++ -o thread testthread.cpp -lpthread

条件变量

#include <stdio.h>

#include <pthread.h>

#include "stdlib.h"

#include "unistd.h"

pthread_mutex_t mutex;

pthread_cond_t cond;

void hander(void *arg)

{

    free(arg);

    (void)pthread_mutex_unlock(&mutex);

}

void *thread1(void *arg)

{

    pthread_cleanup_push(hander, &mutex);

    while()

    {

        printf("thread1 is running\n");

        pthread_mutex_lock(&mutex);

        pthread_cond_wait(&cond, &mutex);

        printf("thread1 applied the condition\n");

        pthread_mutex_unlock(&mutex);

        sleep();

    }

    pthread_cleanup_pop();

}

void *thread2(void *arg)

{

    while()

    {

        printf("thread2 is running\n");

        pthread_mutex_lock(&mutex);

        pthread_cond_wait(&cond, &mutex);

        printf("thread2 applied the condition\n");

        pthread_mutex_unlock(&mutex);

        sleep();

    }

}

int main()

{

    pthread_t thid1,thid2;

    printf("condition variable study!\n");

    pthread_mutex_init(&mutex, NULL);

    pthread_cond_init(&cond, NULL);

    pthread_create(&thid1, NULL, thread1, NULL);

    pthread_create(&thid2, NULL, thread2, NULL);

    sleep();

    do

    {

        pthread_cond_signal(&cond);

    }while();

    sleep();

    pthread_exit();

    return ;

}
#include <pthread.h>

#include <unistd.h>

#include "stdio.h"

#include "stdlib.h"

static pthread_mutex_t mtx = PTHREAD_MUTEX_INITIALIZER;

static pthread_cond_t cond = PTHREAD_COND_INITIALIZER;

struct node

{

    int n_number;

    struct node *n_next;

}*head = NULL;

static void cleanup_handler(void *arg)

{

    printf("Cleanup handler of second thread./n");

    free(arg);

    (void)pthread_mutex_unlock(&mtx);

}

static void *thread_func(void *arg)

{

    struct node *p = NULL;

    pthread_cleanup_push(cleanup_handler, p);

    while ()

    {

        //这个mutex主要是用来保证pthread_cond_wait的并发性

        pthread_mutex_lock(&mtx);

        while (head == NULL)

        {

            //这个while要特别说明一下,单个pthread_cond_wait功能很完善,为何

            //这里要有一个while (head == NULL)呢?因为pthread_cond_wait里的线

            //程可能会被意外唤醒,如果这个时候head != NULL,则不是我们想要的情况。

            //这个时候,应该让线程继续进入pthread_cond_wait

            // pthread_cond_wait会先解除之前的pthread_mutex_lock锁定的mtx,

            //然后阻塞在等待对列里休眠,直到再次被唤醒(大多数情况下是等待的条件成立

            //而被唤醒,唤醒后,该进程会先锁定先pthread_mutex_lock(&mtx);,再读取资源

            //用这个流程是比较清楚的

            pthread_cond_wait(&cond, &mtx);

            p = head;

            head = head->n_next;

            printf("Got %d from front of queue/n", p->n_number);

            free(p);

        }

        pthread_mutex_unlock(&mtx); //临界区数据操作完毕,释放互斥锁

    }

    pthread_cleanup_pop();

    return ;

}

int main(void)

{

    pthread_t tid;

    int i;

    struct node *p;

    //子线程会一直等待资源,类似生产者和消费者,但是这里的消费者可以是多个消费者,而

    //不仅仅支持普通的单个消费者,这个模型虽然简单,但是很强大

    pthread_create(&tid, NULL, thread_func, NULL);

    sleep();

    for (i = ; i < ; i++)

    {

        p = (struct node*)malloc(sizeof(struct node));

        p->n_number = i;

        pthread_mutex_lock(&mtx); //需要操作head这个临界资源,先加锁,

        p->n_next = head;

        head = p;

        pthread_cond_signal(&cond);

        pthread_mutex_unlock(&mtx); //解锁

        sleep();

    }

    printf("thread 1 wanna end the line.So cancel thread 2./n");

    //关于pthread_cancel,有一点额外的说明,它是从外部终止子线程,子线程会在最近的取消点,退出

    //线程,而在我们的代码里,最近的取消点肯定就是pthread_cond_wait()了。

    pthread_cancel(tid);

    pthread_join(tid, NULL);

    printf("All done -- exiting/n");

    return ;

}

信号量

#include <stdlib.h>

#include <stdio.h>

#include <unistd.h>

#include <pthread.h>

#include <semaphore.h>

#include <errno.h>

#define return_if_fail(p) if((p) == 0){printf ("[%s]:func error!/n", __func__);return;}

typedef struct _PrivInfo

{

    sem_t s1;

    sem_t s2;

    time_t end_time;

}PrivInfo;

static void info_init (PrivInfo* thiz);

static void info_destroy (PrivInfo* thiz);

static void* pthread_func_1 (PrivInfo* thiz);

static void* pthread_func_2 (PrivInfo* thiz);

int main (int argc, char** argv)

{

    pthread_t pt_1 = ;

    pthread_t pt_2 = ;

    int ret = ;

    PrivInfo* thiz = NULL;

    thiz = (PrivInfo* )malloc (sizeof (PrivInfo));

    if (thiz == NULL)

    {

        printf ("[%s]: Failed to malloc priv./n");

        return -;

    }

    info_init (thiz);

    ret = pthread_create (&pt_1, NULL, (void*)pthread_func_1, thiz);

    if (ret != )

    {

        perror ("pthread_1_create:");

    }

    ret = pthread_create (&pt_2, NULL, (void*)pthread_func_2, thiz);

    if (ret != )

    {

        perror ("pthread_2_create:");

    }

    pthread_join (pt_1, NULL);

    pthread_join (pt_2, NULL);

    info_destroy (thiz);

    return ;

}

static void info_init (PrivInfo* thiz)

{

    return_if_fail (thiz != NULL);

    thiz->end_time = time(NULL) + ;

    sem_init (&thiz->s1, , );

    sem_init (&thiz->s2, , );

    return;

}

static void info_destroy (PrivInfo* thiz)

{

    return_if_fail (thiz != NULL);

    sem_destroy (&thiz->s1);

    sem_destroy (&thiz->s2);

    free (thiz);

    thiz = NULL;

    return;

}

static void* pthread_func_1 (PrivInfo* thiz)

{

    return_if_fail(thiz != NULL);

    while (time(NULL) < thiz->end_time)

    {

        sem_wait (&thiz->s2);

        printf ("pthread1: pthread1 get the lock./n");

        sem_post (&thiz->s1);

        printf ("pthread1: pthread1 unlock/n");

        sleep ();

    }

    return;

}

static void* pthread_func_2 (PrivInfo* thiz)

{

    return_if_fail (thiz != NULL);

    while (time (NULL) < thiz->end_time)

    {

        sem_wait (&thiz->s1);

        printf ("pthread2: pthread2 get the unlock./n");

        sem_post (&thiz->s2);

        printf ("pthread2: pthread2 unlock./n");

        sleep ();

    }

    return;

}

总结:

互斥锁是是访问共享变量的,防止多线程同时写出现脏数据。

信号量是用来线程同步的,可两线程双向互相通知,也可单向通知。

条件变量是信号量的一种封装,用于线程单向等待另一个线程的通知,也可先后多个线程等待同一个条件变量的唤醒。

参考资料:https://blog.csdn.net/zsf8701/article/details/7844316

Linux 线程同步的三种方法(互斥锁、条件变量、信号量)的更多相关文章

  1. 【转】 Linux 线程同步的三种方法

    线程的最大特点是资源的共享性,但资源共享中的同步问题是多线程编程的难点.linux下提供了多种方式来处理线程同步,最常用的是互斥锁.条件变量和信号量. 一.互斥锁(mutex) 通过锁机制实现线程间的 ...

  2. Java中实现线程同步的三种方法

    实现同步的三种方法 多线程共享数据时,会发生线程不安全的情况,多线程共享数据必须同步. 实现同步的三种方法: 使用同步代码块 使用同步方法 使用互斥锁ReetrantLock(更灵活的代码控制) 代码 ...

  3. java多线程二之线程同步的三种方法

          java多线程的难点是在:处理多个线程同步与并发运行时线程间的通信问题.java在处理线程同步时,常用方法有: 1.synchronized关键字. 2.Lock显示加锁. 3.信号量Se ...

  4. JAVA之线程同步的三种方法

    最近接触到一个图片加载的项目,其中有声明到的线程池等资源需要在系统中线程共享,所以就去研究了一下线程同步的知识,总结了三种常用的线程同步的方法,特来与大家分享一下.这三种方法分别是:synchroni ...

  5. C++11 多线程同步 互斥锁 条件变量

    在多线程程序中,线程同步(多个线程访问一个资源保证顺序)是一个非常重要的问题,Linux下常见的线程同步的方法有下面几种: 互斥锁 条件变量 信号量 这篇博客只介绍互斥量和条件变量的使用. 互斥锁和条 ...

  6. linux c 线程间同步(通信)的几种方法--互斥锁,条件变量,信号量,读写锁

    Linux下提供了多种方式来处理线程同步,最常用的是互斥锁.条件变量.信号量和读写锁. 下面是思维导图:  一.互斥锁(mutex)  锁机制是同一时刻只允许一个线程执行一个关键部分的代码. 1 . ...

  7. Linux下线程同步的几种方法

    Linux下提供了多种方式来处理线程同步,最常用的是互斥锁.条件变量和信号量. 一.互斥锁(mutex) 锁机制是同一时刻只允许一个线程执行一个关键部分的代码.  1. 初始化锁 int pthrea ...

  8. 归纳一下:C#线程同步的几种方法

    转自原文 归纳一下:C#线程同步的几种方法 我们在编程的时候,有时会使用多线程来解决问题,比如你的程序需要在后台处理一大堆数据,但还要使用户界面处于可操作状态:或者你的程序需要访问一些外部资源如数据库 ...

  9. IOS 多线程,线程同步的三种方式

    本文主要是讲述 IOS 多线程,线程同步的三种方式,更多IOS技术知识,请登陆疯狂软件教育官网. 一般情况下我们使用线程,在多个线程共同访问同一块资源.为保护线程资源的安全和线程访问的正确性. 在IO ...

随机推荐

  1. pandas(一)操作Series和DataFrame的基本功能

    reindex:重新索引 pandas对象有一个重要的方法reindex,作用:创建一个适应新索引的新对象 以Series为例 >>> series_obj = Series([4. ...

  2. BIO,NIO和AIO

    BIO:同步阻塞式IO,服务器实现模式为一个连接一个线程,即客户端有连接请求时服务器端就需要启动一个线程进行处理,如果这个连接不做任何事情会造成不必要的线程开销,当然可以通过线程池机制改善. NIO: ...

  3. 07_Warning $HADOOP_HOME is deprecated.去除办法

    Warning $HADOOP_HOME is deprecated.去除办法 警告的出现: 解决方案: 第一种: 去除[/etc/profile]文件中[export HADOOP_HOME=/op ...

  4. <script>放在head内和body内有什么区别

    加载的顺序不一样,你可以把HTML看成从上往下加载的. 例如在网速慢的情况下把js代码放在body底部用户会先看到网页结构,等js加载完成后才出现特效 区别简述: 在HTML body部分中的Java ...

  5. 【鸟哥的Linux私房菜】笔记1

    Linux是什么 从操作系统与cpu架构关系到linux  Richard Mathew Stallman GPL 关于GNU计划 Linux的发展 Linux的核心版本 Linux的特色 Linux ...

  6. Mysql主从复制原理详解

    一.为什么要做主从同步 1.读写分离,降低对主数据库的IO消耗 2.避免数据丢失 3.提高业务系统性能 二.主从同步和集群的区别 1.主从同步 一般需要两台及以上数据库服务器即可(一台用于写入数据,一 ...

  7. java 跨数据库导入大数据

    java 跨数据库导入大数据 /** * java程序跨服务器跨数据库批量导入导出百万级数据 * @param args * @throws Exception */ public static vo ...

  8. jQuery图片下滑切换焦点图

    在线演示 本地下载

  9. async/await方法解析

    欲了解await,必须先了解Promise,可参考: http://www.cnblogs.com/yanze/p/6347646.html 支持度: ES6已支持Promise,ES7也决定支持aw ...

  10. 20145231《Java程序设计》课程总结

    20145231 <Java程序设计>课程总结 每周读书笔记链接汇总 ● 20145231<Java程序设计>第一周学习总结 ●20145231<Java程序设计> ...