Linux中的常用多线程同步方式

Linux多线程同步方式编程 在上述代码中,我们首先初始化了一个读写锁,并创建了3个读线程和2个写线程。在上述代码中,我们首先初始化了一个互斥锁和一个条件变量,并创建了5个线程。然而,在多线程编程中,线程之间的同步是一个重要的问题。通过正确地使用这些同步方式,我们可以实现线程间的同步和通信,确保多线程程序的正确性和效率。互斥锁是一种最常用的同步机制,用于保护临界区资源,确保同一时间只有一个线程可以访问共享数据。条件变量用于在多线程环境中实现线程间的通信和同步。它通常与互斥锁一起使用,以实现更复杂的同步需求,例如线程的等待和唤醒。 阅读详情

嵌入式linux中文站给大家介绍三种Linux中的常用多线程同步方式:互斥量,条件变量,信号量。

1 互斥锁

  互斥锁用来保证一段时间内只有一个线程在执行一段代码。必要性显而易见:假设各个线程向同一个文件顺序写入数据,最后得到的结果一定是灾难性的。

  先看下面一段代码。这是一个读/写程序,它们公用一个缓冲区,并且假定一个缓冲区只能保存一条信息。即缓冲区只有两个状态:有信息或没有信息。

  void reader_function ( void );
  void writer_function ( void );
  char buffer;
  int buffer_has_item=0;
  pthread_mutex_t mutex;
  struct timespec delay;
  void main ( void ){
  pthread_t reader;
  /* 定义延迟时间*/
  delay.tv_sec = 2;
  delay.tv_nec = 0;
  /* 用默认属性初始化一个互斥锁对象*/
  pthread_mutex_init (&mutex,NULL);
  pthread_create(&reader, pthread_attr_default, (void *)&reader_function), NULL);
  writer_function( );
  }
  void writer_function (void){
  while(1){
  /* 锁定互斥锁*/
  pthread_mutex_lock (&mutex);
  if (buffer_has_item==0){
  buffer=make_new_item( );
  buffer_has_item=1;
  }
  /* 打开互斥锁*/
  pthread_mutex_unlock(&mutex);
  pthread_delay_np(&delay);
  }
  }
  void reader_function(void){
  while(1){
  pthread_mutex_lock(&mutex);
  if(buffer_has_item==1){
  consume_item(buffer);
  buffer_has_item=0;
  }
  pthread_mutex_unlock(&mutex);
  pthread_delay_np(&delay);
  }
  }

  这里声明了互斥锁变量mutex,结构pthread_mutex_t为不公开的数据类型,其中包含一个系统分配的属性对象。函数pthread_mutex_init用来生成一个互斥锁。NULL参数表明使用默认属性。如果需要声明特定属性的互斥锁,须调用函数pthread_mutexattr_init。函数pthread_mutexattr_setpshared和函数pthread_mutexattr_settype用来设置互斥锁属性。前一个函数设置属性pshared,它有两个取值,PTHREAD_PROCESS_PRIVATE和PTHREAD_PROCESS_SHARED。前者用来不同进程中的线程同步,后者用于同步本进程的不同线程。在上面的例子中,使用的是默认属性PTHREAD_PROCESS_ PRIVATE。后者用来设置互斥锁类型,可选的类型有PTHREAD_MUTEX_NORMAL、PTHREAD_MUTEX_ERRORCHECK、PTHREAD_MUTEX_RECURSIVE和PTHREAD _MUTEX_DEFAULT。它们分别定义了不同的上锁、解锁机制,一般情况下,选用最后一个默认属性。

  pthread_mutex_lock声明开始用互斥锁上锁,此后的代码直至调用pthread_mutex_unlock为止,均被上锁,即同一时间只能被一个线程调用执行。当一个线程执行到pthread_mutex_lock处时,如果该锁此时被另一个线程使用,那此线程被阻塞,即程序将等待到另一个线程释放此互斥锁。在上面的例子中,使用了pthread_delay_np函数,让线程睡眠一段时间,就是为了防止一个线程始终占据此函数。

  在使用互斥锁的过程中很有可能会出现死锁:两个线程试图同时占用两个资源,并按不同的次序锁定相应的互斥锁,例如两个线程都需要锁定互斥锁1和互斥锁2,a线程先锁定互斥锁1,b线程先锁定互斥锁2,这时就出现了死锁。此时可以使用函数pthread_mutex_trylock,它是函数pthread_mutex_lock的非阻塞版本,当它发现死锁不可避免时,它会返回相应的信息,程序员可以针对死锁做出相应的处理。另外不同的互斥锁类型对死锁的处理不一样,但最主要的还是要程序员自己在程序设计注意这一点。

 2 条件变量

  前一节中我们讲述了如何使用互斥锁来实现线程间数据的共享和通信,互斥锁一个明显的缺点是它只有两种状态:锁定和非锁定。而条件变量通过允许线程阻塞和等待另一个线程发送信号的方法弥补了互斥锁的不足,它常和互斥锁一起使用。使用时,条件变量被用来阻塞一个线程,当条件不满足时,线程往往解开相应的互斥锁并等待条件发生变化。一旦其它的某个线程改变了条件变量,它将通知相应的条件变量唤醒一个或多个正被此条件变量阻塞的线程。这些线程将重新锁定互斥锁并重新测试条件是否满足。一般说来,条件变量被用来进行线程间的同步。

  条件变量的结构为pthread_cond_t,函数pthread_cond_init()被用来初始化一个条件变量。它的原型为:

  extern int pthread_cond_init __P ((pthread_cond_t *__cond,__const pthread_condattr_t *__cond_attr));

  其中cond是一个指向结构pthread_cond_t的指针,cond_attr是一个指向结构pthread_condattr_t的指针。结构pthread_condattr_t是条件变量的属性结构,和互斥锁一样可以用它来设置条件变量是进程内可用还是进程间可用,默认值是PTHREAD_ PROCESS_PRIVATE,即此条件变量被同一进程内的各个线程使用。注意初始化条件变量只有未被使用时才能重新初始化或被释放。释放一个条件变量的函数为pthread_cond_ destroy(pthread_cond_t cond)。

  函数pthread_cond_wait()使线程阻塞在一个条件变量上。它的函数原型为:

  extern int pthread_cond_wait __P ((pthread_cond_t *__cond,

  pthread_mutex_t *__mutex));

  线程解开mutex指向的锁并被条件变量cond阻塞。线程可以被函数pthread_cond_signal和函数pthread_cond_broadcast唤醒,但是要注意的是,条件变量只是起阻塞和唤醒线程的作用,具体的判断条件还需用户给出,例如一个变量是否为0等等,这一点从后面的例子中可以看到。线程被唤醒后,它将重新检查判断条件是否满足,如果还不满足,一般说来线程应该仍阻塞在这里,被等待被下一次唤醒。这个过程一般用while语句实现。

  另一个用来阻塞线程的函数是pthread_cond_timedwait(),它的原型为:

  extern int pthread_cond_timedwait __P ((pthread_cond_t *__cond,

  pthread_mutex_t *__mutex, __const struct timespec *__abstime));

  它比函数pthread_cond_wait()多了一个时间参数,经历abstime段时间后,即使条件变量不满足,阻塞也被解除。

  函数pthread_cond_signal()的原型为:

  extern int pthread_cond_signal __P ((pthread_cond_t *__cond));

  它用来释放被阻塞在条件变量cond上的一个线程。多个线程阻塞在此条件变量上时,哪一个线程被唤醒是由线程的调度策略所决定的。要注意的是,必须用保护条件变量的互斥锁来保护这个函数,否则条件满足信号有可能在测试条件和调用pthread_cond_wait函数之间被发出,从而造成无限制的等待。下面是使用函数pthread_cond_wait()和函数pthread_cond_signal()的一个简单的例子。

pthread_mutex_t count_lock;
  pthread_cond_t count_nonzero;
  unsigned count;
  decrement_count () {
  pthread_mutex_lock (&count_lock);
  while(count==0)
  pthread_cond_wait( &count_nonzero, &count_lock);
  count=count -1;
  pthread_mutex_unlock (&count_lock);
  }
  increment_count(){
  pthread_mutex_lock(&count_lock);
  if(count==0)
  pthread_cond_signal(&count_nonzero);
  count=count+1;
  pthread_mutex_unlock(&count_lock);
  }

  count值为0时,decrement函数在pthread_cond_wait处被阻塞,并打开互斥锁count_lock。此时,当调用到函数increment_count时,pthread_cond_signal()函数改变条件变量,告知decrement_count()停止阻塞。

  函数pthread_cond_broadcast(pthread_cond_t *cond)用来唤醒所有被阻塞在条件变量cond上的线程。这些线程被唤醒后将再次竞争相应的互斥锁,所以必须小心使用这个函数。

3 信号量

  信号量本质上是一个非负的整数计数器,它被用来控制对公共资源的访问。当公共资源增加时,调用函数sem_post()增加信号量。只有当信号量值大于0时,才能使用公共资源,使用后,函数sem_wait()减少信号量。函数sem_trywait()和函数pthread_ mutex_trylock()起同样的作用,它是函数sem_wait()的非阻塞版本。下面逐个介绍和信号量有关的一些函数,它们都在头文件/usr/include/semaphore.h中定义。

  信号量的数据类型为结构sem_t,它本质上是一个长整型的数。函数sem_init()用来初始化一个信号量。它的原型为:

  extern int sem_init __P ((sem_t *__sem, int __pshared, unsigned int __value));

  sem为指向信号量结构的一个指针;pshared不为0时此信号量在进程间共享,否则只能为当前进程的所有线程共享;value给出了信号量的初始值。

  函数sem_post( sem_t *sem )用来增加信号量的值。当有线程阻塞在这个信号量上时,调用这个函数会使其中的一个线程不再阻塞,选择机制同样是由线程的调度策略决定的。

  函数sem_wait( sem_t *sem )被用来阻塞当前线程直到信号量sem的值大于0,解除阻塞后将sem的值减一,表明公共资源经使用后减少。函数sem_trywait ( sem_t *sem )是函数sem_wait()的非阻塞版本,它直接将信号量sem的值减一。

  函数sem_destroy(sem_t *sem)用来释放信号量sem。

  下面来看一个使用信号量的例子。在这个例子中,一共有4个线程,其中两个线程负责从文件读取数据到公共的缓冲区,另两个线程从缓冲区读取数据作不同的处理(加和乘运算)。

 /* File sem.c */
  #include
  #include
  #include
  #define MAXSTACK 100
  int stack[MAXSTACK][2];
  int size=0;
  sem_t sem;
  /* 从文件1.dat读取数据,每读一次,信号量加一*/
  void ReadData1(void){
  FILE *fp=fopen("1.dat","r");
  while(!feof(fp)){
  fscanf(fp,"%d %d",&stack[size][0],&stack[size][1]);
  sem_post(&sem);
  ++size;
  }
  fclose(fp);
  }
  /*从文件2.dat读取数据*/
  void ReadData2(void){
  FILE *fp=fopen("2.dat","r");
  while(!feof(fp)){
  fscanf(fp,"%d %d",&stack[size][0],&stack[size][1]);
  sem_post(&sem);
  ++size;
  }
  fclose(fp);
  }
  /*阻塞等待缓冲区有数据,读取数据后,释放空间,继续等待*/
  void HandleData1(void){
  while(1){
  sem_wait(&sem);
  printf("Plus:%d+%d=%d\n",stack[size][0],stack[size][1],
  stack[size][0]+stack[size][1]);
  --size;
  }
  }
  void HandleData2(void){
  while(1){
  sem_wait(&sem);
  printf("Multiply:%d*%d=%d\n",stack[size][0],stack[size][1],
  stack[size][0]*stack[size][1]);
  --size;
  }
  }
  int main(void){
  pthread_t t1,t2,t3,t4;
  sem_init(&sem,0,0);
  pthread_create(&t1,NULL,(void *)HandleData1,NULL);
  pthread_create(&t2,NULL,(void *)HandleData2,NULL);
  pthread_create(&t3,NULL,(void *)ReadData1,NULL);
  pthread_create(&t4,NULL,(void *)ReadData2,NULL);
  /* 防止程序过早退出,让它在此无限期等待*/
  pthread_join(t1,NULL);
  }

  在Linux下,用命令gcc -lpthread sem.c -o sem生成可执行文件sem。事先编辑好数据文件1.dat和2.dat,假设它们的内容分别为1 2 3 4 5 6 7 8 9 10和 -1 -2 -3 -4 -5 -6 -7 -8 -9 -10 ,运行sem,得到如下的结果:

  Multiply:-1*-2=2
  Plus:-1+-2=-3
  Multiply:9*10=90
  Plus:-9+-10=-19
  Multiply:-7*-8=56
  Plus:-5+-6=-11
  Multiply:-3*-4=12
  Plus:9+10=19
  Plus:7+8=15
  Plus:5+6=11

  从中可以看出各个线程间的竞争关系。而数值并未按原先的顺序显示出来,这是由于size这个数值被各个线程任意修改的缘故。这也往往是多线程编程要注意的问题。

linux下多进程多线程写文件 代码目的是比较write和printf多路写性能。首先fork生成子进程,并且在子进程中重定向标准输出;然后在父子进程中各创建10个线程分别利用printf和write进行写操作;最后通过返回值比较两者性能。 立即下载

相关推荐

开发基于GDL235KBQ6开发板的IAP升级程序(HEX协议+串口空闲中断 + DMA接收数据)

使用GDL235kB开发板,实现串口iap升级程序的bootloader代码编写,app为led灯闪烁,并完成通信c代码

zhaozijuncc的博客 642

Linux下多个进程或线程同时对一个文件进行写操作

http://apps.hi.baidu.com/share/detail/19901173 Linux下多个进程或线程同时对一个文件进行写操作,如何解决冲突? 使用flock(锁定文件或解除锁定),简单可行! 先介绍一下flock函数吧 头文件 #include 定义函数 int flock(int fd,int operation); 函数说明 flock()会依参

拾贝者 3138

PLSQL 14.0.6 下载使用教程

众所周知,PLSQL 只是一个oracle第三方开发测试工具,它依赖oracle 客户端搭配使用,但是oracle 客户端有2G,相当庞大,不建议安装。所以我们如果下载安装好PLSQL,再下载好轻量级的支持远程链接的oracle客户端,这样搭配使用可以的话就最好了,答案是可以的。 第一步: PLSQL 下载与安装 PLSQL 14.0.6 下载地址 : https://www.allroundautomations.com/registered-plsqldev/ 下载下来,除了安装路径更改一下,

qq976511508的博客 2134

Linux线程同步

信号量,互斥锁,条件变量,读写锁对程序的执行过程进行控制,保证对临界资源的访问同一时刻只能有一个进程或线程访问。

dyyfyyds_的博客 484

Qt绘图库对决:QWT与QCustomPlot的实战选型指南

本文为Qt开发者提供了QWT与QCustomPlot两大绘图库的实战选型指南。文章从功能特性、性能资源、开发效率三大维度进行深度对比,并结合工业监控、科学计算、嵌入式设备等典型场景,给出了清晰的决策清单。对于需要专业科学图表(如极坐标、等高线图)的场景推荐QWT;对于追求高性能、实时性、快速开发及嵌入式部署的通用图表需求,QCustomPlot是更优选择。

alpha的博客 241

SoC验证新思路:除了UVM仿真,你还可以试试Cadence JasperGold的形式化验证

本文深入探讨了Cadence JasperGold形式化验证在SoC设计中的创新应用,对比传统UVM仿真验证,详细解析了其数学穷尽性验证优势。通过实战案例展示了JasperGold在总线协议、时钟域交叉等关键场景的验证方法,并提供了混合验证流程设计与效能优化方案,帮助工程师提升验证效率30%以上。

weixin_30566063的博客 120

linux多线程写同一个文件,linux系统多线程写入文件如何保证同步

首先,所有的系统调用都是原子性的。这句话来自TLPI:"All system calls are executed atomically. By this, we mean that the kernel guarantees that all of the steps in a system call are completed as a single operation, without be...

weixin_29545475的博客 1941

分位数映射数据后处理-Quantile Mapping后处理 (R语言)

统计后处理器基本上是统计模型,将观察到的关注变量与从气象或水文模型的直接模型输出(DMO)导出的适当预测变量相关联。统计后处理的重要性早已在气象预报中得到认可。早期的工作包括完善的预测(perfect prognosis),模型输出统计(MOS)和模拟方法(analog method)等模型。 近年来,已经提出了许多其他后处理方法,包括秩直方图校准(rank histogram calibrati...

水滴石穿,绳锯木断 1万+

Linux多线程实现文件读写操作—copy

Linux使用多线程实现文件的复制——copy,对文件进行读取,写入操作!

2201_76058089的博客 2037

876-基于STM32的毫米波雷达智能睡眠监测系统

基于STM32的毫米波雷达智能睡眠监测系统通过非接触式毫米波雷达检测人体呼吸频率和体动次数,结合WIFI数据传输和OLED显示,实现睡眠质量分析与远程监控。系统核心功能包括生理参数采集、阈值设置、数据可视化及远程交互。

m0_50083169的博客 1543

医疗影像分割 | 使用MedSAM训练自己的医学图像分割数据集

摘要 本文详细介绍了使用MedSAM模型训练自定义医学图像数据集的完整流程。主要内容包括:代码下载与环境配置(创建虚拟环境、安装依赖、验证CUDA)、数据集准备(目录结构、格式要求、命名规范及检查工具)、预训练模型下载(不同模型选择建议),以及训练脚本修改(解决文件名匹配、Windows系统NCCL支持、单GPU训练等常见问题)。通过逐步指导,帮助用户快速搭建MedSAM训练环境并适配自己的医学图像数据,实现高效的分割模型训练。

LiRongLu_的博客 489

Linux多线程对同一文件读写

FREAD(3) Linux Programmer's Manual FREAD(3) NAME fread, fwrite - binary stream input/output SYNOPSIS #include <stdio.h> size_t fread(void *ptr, size_t size, size_t nmemb, FILE *str.

qq1337594525的博客 2826

Lammps不同亲疏水性粗糙表面的润湿行为模拟(包含in文件)

Lammps粗糙表面的润湿行为模拟(包含in文件)前言—润湿行为模拟一、物理模型构建二、具体in文件—in文件内循环亲疏水性三、具体in文件—分子模板构建初始模型以及平衡态模拟四、全部代码(基地粗糙表面只提供data文件) 前言—润湿行为模拟 润湿现象:当液体与固体接触时,液体的附着层将沿固体表面延伸。当接触角 θ\rm \thetaθ 为锐角时,液体润湿固体,若θ为零时,液体将展延到全部固体表面上。润湿现象的产生与液体和固体的性质有关。(来自百度百科) 润湿行为的本质是固液之间的相互作用,也就是分子间的范

Rockyoung 7093

java线程同步三种_三种Linux中的常用多线程同步方式浅析

嵌入式linux中文站给大家介绍三种Linux中的常用多线程同步方式:互斥量,条件变量,信号量。1 互斥锁互斥锁用来保证一段时间内只有一个线程在执行一段代码。必要性显而易见:假设各个线程向同一个文件顺序写入数据,最后得到的结果一定是灾难性的。先看下面一段代码。这是一个读/写程序,它们公用一个缓冲区,并且假定一个缓冲区只能保存一条信息。即缓冲区只有两个状态:有信息或没有信息。void reader_...

weixin_35934979的博客 139

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

深度学习工具包 DeepLearningToolbox

深度学习工具包Deprecation notice.-----This toolbox is outdated and no longer maintained.There are much better tools available for deep learning than this toolbox, e.g. [Theano](http://deeplearning.net/software/theano/), [torch](http://torch.ch/) or [tensorflow](http://www.tensorflow.org/)I would suggest you use one of the tools mentioned above rather than use this toolbox.Best, Rasmus.DeepLearnToolbox================A Matlab toolbox for Deep Learning.Deep Learning is a new subfield of machine learning that focuses on learning deep hierarchical models of data.It is inspired by the human brain's apparent deep (layered, hierarchical) architecture.A good overview of the theory of Deep Learning theory is[Learning Deep Architectures for AI](http://www.iro.umontreal.ca/~bengioy/papers/ftml_book.pdf)For a more informal introduction, see the following videos by Geoffrey Hinton and Andrew Ng.* [The Next Generation of Neural Networks](http://www.youtube.com/watch?v=AyzOUbkUf3M) (Hinton, 2007)* [Recent Developments in Deep Learning](http://www.youtube.com/watch?v=VdIURAu1-aU) (Hinton, 2010)* [Unsupervised Feature Learning and Deep Learning](http://www.youtube.com/watch?v=ZmNOAtZIgIk) (Ng, 2011)If you use this toolbox in your research please cite [Prediction as a candidate for learning deep hierarchical models of data](http://www2.imm.dtu.dk/pubdb/views/publication_details.php?id=6284)```@MASTERSTHESIS\{IMM2012-06284, author = "R. B. Palm", title = "Prediction as a candidate for learning deep hierarchical models of data", year = "2012",}```Contact: rasmusbergpalm at gmail dot comDirectories included in the toolbox-----------------------------------`NN/` - A library for Feedforward Backpropagation Neural Networks`CNN/` - A library for Convolutional Neural Networks`DBN/` - A library for Deep Belief Networks`SAE/` - A library for Stacked Auto-Encoders`CAE/` - A library for Convolutional Auto-Encoders`util/` - Utility functions used by the libraries`data/` - Data used by the examples`tests/` - unit tests to verify toolbox is workingFor references on each library check REFS.mdSetup-----1. Download.2. addpath(genpath('DeepLearnToolbox'));Example: Deep Belief Network---------------------```matlabfunction test_example_DBNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit RBM and visualize its weightsrand('state',0)dbn.sizes = [100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);figure; visualize(dbn.rbm{1}.W'); % Visualize the RBM weights%% ex2 train a 100-100 hidden unit DBN and use its weights to initialize a NNrand('state',0)%train dbndbn.sizes = [100 100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);%unfold dbn to nnnn = dbnunfoldtonn(dbn, 10);nn.activation_function = 'sigm';%train nnopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.10, 'Too big error');```Example: Stacked Auto-Encoders---------------------```matlabfunction test_example_SAEload mnist_uint8;train_x = double(train_x)/255;test_x = double(test_x)/255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit SDAE and use it to initialize a FFNN% Setup and train a stacked denoising autoencoder (SDAE)rand('state',0)sae = saesetup([784 100]);sae.ae{1}.activation_function = 'sigm';sae.ae{1}.learningRate = 1;sae.ae{1}.inputZeroMaskedFraction = 0.5;opts.numepochs = 1;opts.batchsize = 100;sae = saetrain(sae, train_x, opts);visualize(sae.ae{1}.W{1}(:,2:end)')% Use the SDAE to initialize a FFNNnn = nnsetup([784 100 10]);nn.activation_function = 'sigm';nn.learningRate = 1;nn.W{1} = sae.ae{1}.W{1};% Train the FFNNopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.16, 'Too big error');```Example: Convolutional Neural Nets---------------------```matlabfunction test_example_CNNload mnist_uint8;train_x = double(reshape(train_x',28,28,60000))/255;test_x = double(reshape(test_x',28,28,10000))/255;train_y = double(train_y');test_y = double(test_y');%% ex1 Train a 6c-2s-12c-2s Convolutional neural network %will run 1 epoch in about 200 second and get around 11% error. %With 100 epochs you'll get around 1.2% errorrand('state',0)cnn.layers = { struct('type', 'i') %input layer struct('type', 'c', 'outputmaps', 6, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %sub sampling layer struct('type', 'c', 'outputmaps', 12, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %subsampling layer};cnn = cnnsetup(cnn, train_x, train_y);opts.alpha = 1;opts.batchsize = 50;opts.numepochs = 1;cnn = cnntrain(cnn, train_x, train_y, opts);[er, bad] = cnntest(cnn, test_x, test_y);%plot mean squared errorfigure; plot(cnn.rL);assert(er<0.12, 'Too big error');```Example: Neural Networks---------------------```matlabfunction test_example_NNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);% normalize[train_x, mu, sigma] = zscore(train_x);test_x = normalize(test_x, mu, sigma);%% ex1 vanilla neural netrand('state',0)nn = nnsetup([784 100 10]);opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samples[nn, L] = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.08, 'Too big error');%% ex2 neural net with L2 weight decayrand('state',0)nn = nnsetup([784 100 10]);nn.weightPenaltyL2 = 1e-4; % L2 weight decayopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex3 neural net with dropoutrand('state',0)nn = nnsetup([784 100 10]);nn.dropoutFraction = 0.5; % Dropout fraction opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex4 neural net with sigmoid activation functionrand('state',0)nn = nnsetup([784 100 10]);nn.activation_function = 'sigm'; % Sigmoid activation functionnn.learningRate = 1; % Sigm require a lower learning rateopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex5 plotting functionalityrand('state',0)nn = nnsetup([784 20 10]);opts.numepochs = 5; % Number of full sweeps through datann.output = 'softmax'; % use softmax outputopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex6 neural net with sigmoid activation and plotting of validation and training error% split training data into training and validation datavx = train_x(1:10000,:);tx = train_x(10001:end,:);vy = train_y(1:10000,:);ty = train_y(10001:end,:);rand('state',0)nn = nnsetup([784 20 10]); nn.output = 'softmax'; % use softmax outputopts.numepochs = 5; % Number of full sweeps through dataopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, tx, ty, opts, vx, vy); % nntrain takes validation set as last two arguments (optionally)[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');```[![Bitdeli Badge](https://d2weczhvl823v0.cloudfront.net/rasmusbergpalm/deeplearntoolbox/trend.png)](https://bitdeli.com/free "Bitdeli Badge")

【linux多线程】c++多线程的同步方式

linux多线程,C++多线程,线程同步,互斥锁,条件变量,读写锁,自旋锁,信号量,关卡

shuaixio的博客 2035

迈瑞BS系列全自动生化分析仪LIS协议接口手册(内含HL7和ASTM)

迈瑞BS系列全自动生化分析仪LIS协议接口手册,内含HL7和ASTM)

Linux多线程同步方式

Linux多线程同步方式 http://www.cnblogs.com/cchust/p/4252500.html    当多个线程共享相同的内存时,需要确保每个线程看到一致的数据视图,当多个线程同时去修改这片内存时,就可能出现偏差,得到与预期不符合的值。为啥需要同步,一件事情逻辑上一定是有序的,即使在并发环境下;而操作系统对于多线程不会自动帮我们串行化,所以需要我们通过操

zdy0_2004的专栏 592

怀旧版电脑GBC模拟器

再现原版GBC掌机的界面,电脑运行连游戏界面都一样大小,很怀旧,很真实,(英文版)强烈推荐,很小的文件,很难才找到的。

多线程优点及同步方式

一、多线程优点 1.通常启动一个进程,要为该进程分配独立的地址空间,建立多个数据表来维护进程的代码段、堆栈段和数据段,比较耗费系统资源。一个进程创建多线程可以使用相同的地址空间,共享大部分数据,启动一个线程所花费的空间远远小于进程所需空间,而且启动线程花费的时间也比进程花费时间少很多。 2.线程间通讯方便,以为线程之间具有共同的地址空间,共享大部分数据资源 3.提高应用响应速度,将耗时工作放

Helloguoke的专栏 1398

Linux下的线程同步方式

信号量 信号量主要就是PV操作 代码实现: 互斥锁 互斥锁就是在多线程中,当其中某一线程需要对关键代码访问时,需要先获得一个锁,等访问完代码之后再释放这个锁,防止同一时间其它线程访问这段代码。 读写锁 条件变量 ...

程序员的规则 425

【Linux系统】Linux多线程详解

由上图可以很好地理解线程为什么是CPU调度的基本单位,在CPU看来,它只关心一个独立的执行流,无论进程内部是一个还是多个执行流,CPU都是以task_struct为单位来调度的。如果计算密集型线程的数量比可用的处理器多,那么可能会有较大的性能损失,这里的性能损失指的是增加了额外的同步和调度开销,而可用的资源不变。在操作系统的的视角下,Linux下没有真正意义的线程,而是用进程模拟的线程(LWP,轻量级进程),所以Linux不会提供直接创建线程的系统调用,最多提供创建轻量级进程的接口。个字节,也就是1MB。

fufufu_的博客 6772

Linux多线程编程

Linux多线程编程一、线程理论基础二、多线程程序设计三、线程==同步==(按顺序) 一、线程理论基础 有了进程,为何还要引入线程呢?使用多线程有哪些好处? 1、和进程相比,线程是一种非常节俭的多任务操作方式,启动一个新的进程必须分配给它独立的地址空间,建立众多的数据表维护它的代码段、堆栈段、数据段,这是一种昂贵的多任务工作方式 运行于一个进程中的多线程,它们之间使用相同的地址空间,而且线程间彼此切换所需的时间也远远小于进程间切换所需要的时间 2、线程间方便的通讯机制,对不同进程来说,它们具有独立的数据空间

qq_46186025的博客 4808

photon四种同步方式_【Linux】多线程同步的四种方式

背景问题:在特定的应用场景下,多线程不进行同步会造成什么问题?通过多线程模拟多窗口售票为例:#include #include#include#include#include#includeusing namespacestd;int ticket_sum=20;void *sell_ticket(void *arg){for(int i=0; i<20; i++){if(ticket_su...

weixin_39977276的博客 189

Linux下多线程中的信号处理

多线程中的信号处理问题非阻塞线程和阻塞线程通过pthread_kill()发送信号的不同反应关于sigactionsigaction在主线程中注册sigaction不在主线程中注册如果不用pthread_kill信号发生时,哪个线程会收到?注册两种信号,直接发送SIGINT,指定线程发送SIGALRM(主线程不阻塞SIGINT版)主线程阻塞SIGINT信号(阻塞信号集创建线程之后)主线程阻塞SIGINT信号(阻塞信号集创建线程之前)使用kill函数来测试 参考https://www.cnblogs.com/

清风 4564

Linux多线程同步

一般情况下,每一个共享资源对应一个把互斥锁,锁的个数和线程的个数无关。当线程调用这个函数,并且sem中的资源数>0,线程不会阻塞,线程会占用sem中的一个资源,因此资源数-1,直到sem中的资源数减为0时,资源被耗尽,但是线程不会被阻塞,直接返回错误号,因此可以在程序中添加判断分支,用于处理获取资源失败之后的情况。当线程调用这个函数,并且sem中的资源数>0,线程不会阻塞,线程会占用sem中的一个资源,因此资源数-1,直到sem中的资源数减为0时,资源被耗尽,因此线程也就被阻塞了。

qq_40896190的博客 1331
上一篇: Linux多进程与多线程的深度比较
下一篇: 数据库分库分表(sharding)系列
kobejayandy
博客等级 码龄18年 2853粉丝 43原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值