pthread

iOS开发之用到的几种锁整理

*爱你&永不变心* 提交于 2019-12-19 16:36:09
1. iOS中的互斥锁 在编程中,引入对象互斥锁的概念,来保证共享数据操作的完整性。每个对象都对应于一个可称为“互斥锁”的标记,这个标记用来保证在任一时刻,只能有一个线程访问对象。 1.1 @synchronized (self) - (void)lock1 { @synchronized (self) { // 加锁操作 }} 1.2 NSLock - (void)lock2 { NSLock *xwlock = [[NSLock alloc] init]; XWLogBlock logBlock = ^ (NSArray *array) { [xwlock lock]; for (id obj in array) { NSLog(@"%@",obj); } [xwlock unlock]; }; dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ NSArray *array = @[@1,@2,@3]; logBlock(array); });} 1.3 pthread pthread除了创建互斥锁,还可以创建递归锁、读写锁、once等锁 __block pthread_mutex_t mutex; pthread_mutex_init(&mutex, NULL);

026 UNIX再学习 -- 线程同步

六月ゝ 毕业季﹏ 提交于 2019-12-18 22:05:52
一、为什么要线程同步 当多个控制线程共享相同的内存时,需要确保每个线程看到一致的数据视图。如果每个线程使用的变量都是其他线程不会读取和修改的,那么就不存在一致性问题。同样,如果变量时只读的,每个线程同时读取该变量也不会有一致性问题。但是, 当一个线程可以修改的变量,其他线程也可以读取或者修改的时候,我们就需要对这些线程进行同步,确保它们在访问变量的存储内容时不会访问到无效的值 。 当一个线程修改变量时,其他线程在读取这个变量时可能会看到一个不一致的值。在变量修改时间多于一个存储器访问周期的处理器结构中,当存储器读与存储器写这两个周期交叉时,这种不一致就会出现。当然,这种行为是与处理器体系结构相关的,但是可移植的程序并不能对使用何种处理器体系结构做出任何假设。 上图中描述了两个线程读写相同变量的假设例子。在这个例子中,线程 A 读取变量然后给这个变量赋予一个新的数值,但写操作需要两个存储器周期。当线程 B 在这两个存储器写周期中间读取这个变量时,它就会得到不一致的值。 为了解决这个问题,线程不得不使用锁,同一时间只允许一个线程访问该变量。 如果线程 B 希望读取变量,它首先要获取锁。同样,当线程 A 更新变量时,也需要获取同样的这把锁。这样,线程 B 在线程 A 释放锁以前就不能读取变量。 总结一下, 多线程共享进程中的资源,多个线程同时访问相同的共享资源时,需要相互协调

同步:生产者消费者模型(条件变量与信号量)

本小妞迷上赌 提交于 2019-12-18 02:16:00
同步 什么是同步: 通过条件判断实现对临界资源访问的合理性 实现: 条件变量:当一个线程互斥地访问某个变量时,它可能发现在其它线程改变状态之前,它什么也做不了。所以用条件变量可以睡眠的等待某一种条件出现。 原理: 向外提供一个等待队列,以及等待与唤醒的功能 生产者消费者模型 一、一个交易场所 二、两个角色:生产者和消费者 三、三种关系: 生产者和生产者:互斥 生产者和消费者:互斥与同步 消费者和消费者:互斥 优点: 解耦 支持并发 忙闲不均 pthread_cond_wait 调用等待时释放锁,唤醒时重新获得锁 生产者消费者模型 10 class BlockQueue 11 { 12 private : 13 queue < int > q ; 14 int cap ; 15 pthread_mutex_t lock ; 16 pthread_cond_t c_cond ; 17 pthread_cond_t p_cond ; 55 public : 56 BlockQueue ( int cap_ = 4 ) 57 : cap ( cap_ ) 58 { 59 pthread_mutex_init ( & lock , nullptr ) ; 60 pthread_cond_init ( & c_cond , nullptr ) ; 61 pthread_cond_init (

linux C++ pthread线程操作入门

為{幸葍}努か 提交于 2019-12-17 19:12:47
线程操作: 我们要做的1.创建线程 2.线程阻塞 (当线程结束后,主线程才结束) 3.线程返回 (获取线程返回的内容) // 函数的格式必须是这样的. void* name(void * param) void *semopFun(void *param) { cout << "NIHao" << endl; sleep(1); cout<<"thread out"<<endl; /* 线程结束后,传值出去, 给pthread_join()的参数2 */ pthread_exit((void *)1); } int main() { pthread_t semop_threadID = NULL; pthread_create(&semop_threadID, NULL, semopFun, NULL); /* pthread_join 参数1:线程标识符 参数2:pthread_exit()参数返回 如果线程还未运行完毕主线程会被阻塞在此,不再向下执行. */ void *p = NULL; pthread_join(semop_threadID, &p); cout << "p: " <<(int*) p << endl; cout << "OVER" << endl; return 0; } 运行结果: NIHao thread out p: 0x1 OVER 来源:

条件变量与生产者消费者问题

佐手、 提交于 2019-12-17 08:57:23
文章目录 使用 if而非 while且只有一个条件变量 使用while但只有一个条件变量 使用while且有两个条件变量 扩展缓冲区大小(从1到数组) 本文主要是探讨<<操作系统导论>>一书第30章-条件变量的知识. 书中介绍了条件变量的概念, 并将条件变量运用在生产者消费者问题中. 从最简单的情况开始, 列举了使用条件变量解决生产者消费者问题的几种错误用法. 本文主要是对这几种情况的代码模拟分析, 分为以下四个部分 使用 if而非 while且只有一个条件变量 使用while但只有一个条件变量 使用while且有两个条件变量 扩展缓冲区大小(从1到数组) 使用 if而非 while且只有一个条件变量 书中提供的第一个方案(有问题), 给生产者和消费者共用一个条件变量, 且使用if来判断缓存区 问题: wait的条件使用了if而不是while, 导致如果有多个消费者的情况, 当一个阻塞的消费者被生产者唤醒了, 准备执行但这时另一个消费者抢占执行并进行了消费导致缓冲区空了. 这时切换到第一个消费者消费, 因为缓冲区空了触发断言, 程序错误. 如果换成while, 那么第二个消费者在醒来的时候, 就会再判断一下条件是否成立, 由于被另一个消费者消费了, 所以它又会调用wait被阻塞. 需要注意wait函数的执行过程. 当一个线程执行wait的时候, 会释放它持有的锁,

编程小知识之 虚假唤醒(spurious wakeup)

此生再无相见时 提交于 2019-12-17 08:36:52
本文简单介绍了一些 虚假唤醒(spurious wakeup) 相关的知识 (注: 本文假设读者对多线程开发有一定了解) 高层次的多线程编程中, 条件变量 是个常见的同步方法,跟传统仅使用 互斥量 的方法相比,条件变量可以减少锁的竞争. 拿 Pthread 举例,一个常见的条件变量的使用示例大概是这个样子的: // flag for sync bool g_signaled = false; pthread_mutex_t g_mutex; pthread_cond_t g_cond; // wait method void wait() { pthread_mutex_lock(&g_mutex); while (!g_signaled) { pthread_cond_wait(&g_cond, &g_mutex); } g_signaled = false; pthread_mutex_unlock(&g_mutex); } // signal method void signal() { pthread_mutex_lock(&g_mutex); g_signaled = true; pthread_mutex_unlock(&g_mutex); pthread_cond_signal(&g_cond); } 代码中调用的 pthread_cond_wait 方法

BSD库函数手册翻译之pthread_join函数

有些话、适合烂在心里 提交于 2019-12-17 04:32:36
名称 pthread_join -- 等待线程结束 概要 #include <pthread.h> int pthread_join(pthread_t thread,void **value_ptr); 描述 除非目标线程已经终止,否则函数pthread_join()会 暂停调用线程 的 执行 ,直到 目标线程终止 为止。 当传入一个非NULL的参数value_ptr 来调用函数pthread_join() 并成功返回时,正在终止的线程传给函数pthread_exit() 的值被储存在由 value_ptr 所引用的位置。当函数pthread_join() 成功返回时,目标线程已经被终止了。对同一个目标线程同时多次调用函数pthread_join() 的结果是未定义的。若 调用函数pthread_join()的线程被取消 ,则 目标线程未被分离 。 返回值 若执行成功,则函数 pthread_join()将返回零。否则,将返回一个错误码来指示错误。 错误 函数pthread_join()在以下情形下会失败: [EINVAL] 实现已经检测到由线程指定的值没有引用到可连接的线程。 [ESRCH] 没有发现对应于给定线程ID thread的线程。 [EDEADLK] 检测到死锁或参数thread的值指定的是调用函数pthread_join()的线程。 另请参阅: wait(2),

C 与 多线程(1)

故事扮演 提交于 2019-12-14 06:11:20
C 与 多线程(1) 我们可以用C编写多线程程序吗? C 语言标准不支持多线程 POSIX Threads (or Pthreads) is a POSIX standard for threads. gcc compiler 提供了一种 pthread 的实现 一个简单的C程序来演示pthread基本功能的使用 请注意,下面的程序只能与带有pthread库的C编译器一起编译。 # include <stdio.h> # include <stdlib.h> # include <unistd.h> //Header file for sleep(). man 3 sleep for details. # include <pthread.h> // A normal C function that is executed as a thread // when its name is specified in pthread_create() void * myThreadFun ( void * vargp ) { sleep ( 1 ) ; printf ( "Printing GeeksQuiz from Thread \n" ) ; return NULL ; } int main ( ) { pthread_t thread_id ; printf ( "Before

Linux线程池

流过昼夜 提交于 2019-12-13 11:25:53
大多数的网络服务器,包括Web服务器都具有一个特点,就是单位时间内必须处理数目巨大的连接请求,但是处理时间却是比较短的。在传统的多线程服务器模型中是这样实现的:一旦有个请求到达,就创建一个新的线程,由该线程执行任务,任务执行完毕之后,线程就退出。这就是"即时创建,即时销毁"的策略。尽管与创建进程相比,创建线程的时间已经大大的缩短,但是如果提交给线程的任务是执行时间较短,而且执行次数非常频繁,那么服务器就将处于一个不停的创建线程和销毁线程的状态。这笔开销是不可忽略的,尤其是线程执行的时间非常非常短的情况。   线程池就是为了解决上述问题的,它的实现原理是这样的:在应用程序启动之后,就马上创建一定数量的线程,放入空闲的队列中。这些线程都是处于阻塞状态,这些线程只占一点内存,不占用CPU。当任务到来后,线程池将选择一个空闲的线程,将任务传入此线程中运行。当所有的线程都处在处理任务的时候,线程池将自动创建一定的数量的新线程,用于处理更多的任务。执行任务完成之后线程并不退出,而是继续在线程池中等待下一次任务。当大部分线程处于阻塞状态时,线程池将自动销毁一部分的线程,回收系统资源。   下面是一个简单线程池的实现,这个线程池的代码是我参考网上的一个例子实现的,由于找不到出处了,就没办法注明参考自哪里了。它的方案是这样的:程序启动之前,初始化线程池,启动线程池中的线程,由于还没有任务到来