15-多线程互斥和同步
来源:互联网 发布:淘宝关注的主播在哪里 编辑:程序博客网 时间:2024/05/16 18:52
- 一什么是多线程
- 二多线程函数
- 三多线程互斥
- 四多线程同步
- 五代码
注意:与进程区分开来。
线程同步:多个线程按照先后顺序执行,就像是排了队列一样,一个一个来;
线程互斥:多个线程对同个资源操作,为了保证被访问资源的原子性(一次只能有一个线程使用资源),所以要互斥。
一、什么是多线程
* 线程就是“轻量级”的进程。 * 线程与创建它的进程共享代码段,数据段。 * 线程拥有自己独立的栈
二、多线程函数
(转)所谓最简单的多线程编程,就是通过pthread_create,pthread_join,pthread_exit 3个api实现线程的创建与终止,而创建的线程只做些简单的工作,如printf一些文字信息。
使用pthread_create,pthread_join,pthread_exit 进行多线程编程的模型如下图所示:
- pthread_create
//原型:int pthread_create(pthread_t * thread, const pthread_attr_t * attr, void * (*start_routine)(void *), void *arg) /** @function :按照给定的线程属性attr,在一个进程(process)里创建一个新的线程(thread) * @param attr: * 如果attr为NULL,则内部使用默认的属性创建线程。如果在创建线程之后修改attr,则不会对已经创建的线程产生作用。 * @param thread: * 创建线程成功后,将thread id存储在thread里,返回给调用者。否则thrad的值是未定义的。 * @param start_routine: * 线程创建成功后,开始执行线程的入口函数start_routine。 * @param arg: * 调用者通过arg指定线程入口函数start_routine专用的参数指针。 * @return : * 0 创建成功返回0 * EAGAIN 超出了系统限制,如创建的线程太多,一个进程最多创建线程个数PTHREAD_THREADS_MAX。 * EINVAL attr 的值无效 * @note pthread_create创建线程后,线程入口函数即开始执行,不需要显示控制start_routine开始执行。 * 如果确实需要将此过程分为create和start2步来控制start_routine稍后执行, * start_routine可以通过等待一个条件变量(condition variable)进行同步的方式实现。 * Compile and link with -pthread.例如:gcc -lphread*/
- pthread_exit
/**- @function void pthread_exit(void *status)
- 终止调用者线程,
- @param status:
- 通过status设置退出状态,与pthread_join配对使用
- @return :
- 无返回值,也不返回到其调用方。
- @note
- 如果调用线程尚未分离,则线程ID 和status 指定的退出状态将保持不变,直到应用程序调用pthread_join() 以等待该线程。
- 否则,将忽略status。线程ID 可以立即回收。
*/
- pthread_join
/**- @function int pthread_join(pthread_t thread, void **status);
- 等待thread线程终止
- 如果thread指代的线程还没有终止,将导致调用线程挂起,直到thread指代的线程终止为止。
- @param thread:
- 所等待的的终止线程
- @param status:
- 如果status的值不等于NULL,那么它的值是通过pthread_exit传递过来的。
- @return :
- 0 线程已经终止
- ESRCH 多个线程不能等待同一个线程完成,否则仅有一个线程会成功完成。其他线程将终止,并返回ESRCH 错误。
- EINVAL 一般表示thread是无效的参数
- EDEADLK 检查到死锁状态
- @note
- 如果调用线程尚未分离,则线程ID 和status 指定的退出状态将保持不变,直到应用程序调用pthread_join() 以等待该线程。
- 否则,将忽略status。线程ID 可以立即回收。
*/
三、多线程互斥:
1. 线程的互斥函数有: 1. 互斥函数的初始化:pthread_mutex_init(); 2. 互斥函数的锁定函数pthread_mutex_lock(); 3. 互斥函数的解锁函数pthread_mutex_unlock(); 4. 互斥函数的销毁函数pthread_mutex_destroy()。
四、多线程同步:
1. 初始化 * pthread_cond_t cond_ready=PTHREAD_COND_INITIALIZER;2. 等待条件成熟 * pthread_cond_wait(&cond_ready, &mut);3. 设置条件成熟 * pthread_cond_signal(&cond_ready);
五、代码
/** Filename : pthread.c* Date : 2017-04-24* Author : Chen-nan* Description: 这个程序是测试线程的互斥访问的。即:多个线程同时对一个资源进行访问时候,为了保证所操作资源的原子性,一次只能一个线程访问。* */* #include <pthread.h>#include <unistd.h>#include <stdio.h>pthread_t pthread[2] ;int count = 0 ;pthread_mutex_t mutex ;/*线程A的函数*/void * funa( ) { int i = 0 ; for( i=0 ; i<10 ; ++i ) { pthread_mutex_lock( &mutex ) ; ++count ; printf( "chen is : %d \n" , count ) ; pthread_mutex_unlock( &mutex ) ; } pthread_exit(NULL) ;} /*线程B的函数*/void * funb( ) { int i = 0 ; for( i=0 ; i<5 ; ++i ) { pthread_mutex_lock( &mutex ) ; ++count ; printf( "nan is : %d \n" , count ) ; pthread_mutex_unlock( &mutex ) ; } pthread_exit(NULL) ;}int main ( int argc , char **argv ) { pthread_mutex_init( &mutex , NULL ) ; /*创建线程A*/ pthread_create( &pthread[0] , NULL , funa , NULL ) ; /*创建线程B*/ pthread_create( &pthread[1] , NULL , funb , NULL ) ; /*等待线程A完成*/ pthread_join( pthread[0] , NULL ) ; /*等待线程B完成*/ pthread_join( pthread[1] , NULL ) ; return 0 ;}
/** Filename : pthread.c* Date : 2017-04-24* Author : Chen-nan* Description: 这个程序是测试线程的同步访问的。即:多个线程按照一定顺序先后执行。* */#include <pthread.h>#include <unistd.h>#include <stdio.h>pthread_t pthread[2] ;int count = 0 ;pthread_mutex_t mutex ;/*创建条件变量,其实就是创建一个信号,通过发送信号,唤醒其他进程。*/pthread_cond_t flag=PTHREAD_COND_INITIALIZER;/*线程A的函数*/void * funa( ) { int i = 0 ; for( i=0 ; i<10 ; ++i ) { pthread_mutex_lock( &mutex ) ; ++count ; printf( "chen is : %d \n" , count ) ; pthread_mutex_unlock( &mutex ) ; if( 10==count ) { printf( "--------chen is finish .-------------\n") ; /*条件成熟,发送条件变量(信号)通过其他进程可以开工了*/ pthread_cond_signal( &flag ) ; } } pthread_exit(NULL) ;} /*线程B的函数*/void * funb( ) { int i = 0 ; pthread_mutex_lock( &mutex ) ; if( 10>count ) { /*判断当前条件是否可以执行,不行就挂起等待。直到有其他线程发送信号为止。这个函数包含了一个互斥锁,进入挂起状态时会解锁(所以前面有一个互斥锁的锁定),当收到信号后就会加上互斥锁(所以后边要解锁)。*/ pthread_cond_wait( &flag , &mutex ) ; } for( i=0 ; i<5 ; ++i ) { ++count ; printf( "nan is : %d \n" , count ) ; pthread_mutex_unlock( &mutex ) ; } pthread_exit(NULL) ;}int main ( int argc , char **argv ) { pthread_mutex_init( &mutex , NULL ) ; /*创建线程A*/ pthread_create( &pthread[0] , NULL , funa , NULL ) ; /*创建线程B*/ pthread_create( &pthread[1] , NULL , funb , NULL ) ; /*等待线程A完成*/ pthread_join( pthread[0] , NULL ) ; /*等待线程B完成*/ pthread_join( pthread[1] , NULL ) ; return 0 ;}
0 0
- 15-多线程互斥和同步
- 多线程互斥和同步
- windows多线程同步和互斥关系
- 多线程的同步和互斥简介
- 多线程的同步和互斥
- 多线程理解--互斥和同步
- 多线程的同步和互斥
- 多线程的互斥和同步
- 多线程互斥同步
- 多线程互斥同步
- 多线程同步互斥
- 多线程同步与互斥
- 多线程同步与互斥
- 多线程同步与互斥
- 多线程同步与互斥
- 多线程同步与互斥
- MFC多线程同步互斥
- 多线程互斥与同步
- 朴素贝叶斯入门
- Java集合之ArrayList
- windows 常用 cmd 命令
- GIT配置SSH key
- Leetcode -- 36. Valid Sudoku
- 15-多线程互斥和同步
- 根据父子关系建立二叉树
- list容器的遍历删除
- 继承(Inheritance)与复合(Composition)关系下的构造与析构
- 2017,回来了~
- Shell 练习题 21—30,内附答案
- 关于如何单独失能STM32 TIM通道的方法
- 设计模式-3-建造者模式
- Bagging – building an ensemble of classifers from bootstrap samples