iOS-dispatch_semaphore的使用

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了iOS-dispatch_semaphore的使用相关的知识,希望对你有一定的参考价值。

参考技术A 从dispatch_semaphore_t抽象概念上理解,它是用来记数的信号量。我们可以和系统的引用计数来类比,无非就是一个整型值的加加减减。
我们在利用GCD的信号量机制来处理一些日常功能的时候,主要会用到的方法有三个:

通常等待信号量和发送信号量的函数是成对出现的。并发执行任务时候,在当前任务执行之前,用dispatch_semaphore_wait函数进行等待(阻塞),直到上一个任务执行完毕后且通过dispatch_semaphore_signal函数发送信号量(使信号量的值加1),dispatch_semaphore_wait函数收到信号量之后判断信号量的值大于等于1,会再对信号量的值减1,然后当前任务可以执行,执行完毕当前任务后,再通过dispatch_semaphore_signal函数发送信号量(使信号量的值加1),通知执行下一个任务......如此一来,通过信号量,就达到了并发队列中的任务同步执行的要求。

众所周知,并发队列中的任务,由异步线程执行的顺序是不确定的,两个任务分别由两个线程执行,很难控制哪个任务先执行完,哪个任务后执行完。但有时候确实有这样的需求:两个任务虽然是异步的,但仍需要同步执行。这时候,GCD信号量就可以大显身手了。

执行结果:

执行结果:

使用异步组(dispatch group)可以实现在同一个组内的内务执行全部完毕之后再执行最后的处理。但是同一组内的block任务的执行顺序是不可控的。

执行结果:

不使用信号量的情况

使用信号量的情况

虽然我们把两个任务(假设每个任务都叫做T)加到了异步组中,但是每个任务T又都有一个异步回调T'(这个异步的回调T'操作并不会立即触发,如果T'是一个网络请求的异步回调,这个回调的时机取决于网络数据返回的时间,有可能很快返回,有可能很久返回),相当于每个任务T又都有自己的任务T',加起来就是4个任务。因为异步组只对自己的任务T(block)负责,并不会对自己任务的任务T'(block中的block)负责,异步组把自己的任务执行完后会立即返回,并不会等待自己的任务的任务执行完毕。显然,上面这种在异步组中再异步的执行顺序是不可控的。

Kettle java脚本组件的使用说明(简单使用升级使用)

文章目录

前言

  如果您觉得有用的话,记得给博主点个赞,评论,收藏一键三连啊,写作不易啊^ _ ^。
  而且听说点赞的人每天的运气都不会太差,实在白嫖的话,那欢迎常来啊!!!


Kettle java脚本组件的使用说明(简单使用、升级使用)

01 简单使用

获取java脚本组件

打开你刚刚移动过来的java脚本

几个地方要记住

main方法,
点击后可以看到出来一大坨代码:

public boolean processRow(StepMetaInterface smi, StepDataInterface sdi) throws KettleException
if (first)
first = false;
/* TODO: Your code here. (Using info fields)
FieldHelper infoField = get(Fields.Info, “info_field_name”);
RowSet infoStream = findInfoRowSet(“info_stream_tag”);
Object[] infoRow = null;
int infoRowCount = 0;
// Read all rows from info step before calling getRow() method, which returns first row from any
// input rowset. As rowMeta for info and input steps varies getRow() can lead to errors.
while((infoRow = getRowFrom(infoStream)) != null)
// do something with info data
infoRowCount++;

/

Object[] r = getRow();
if (r == null)
setOutputDone();
return false;

// It is always safest to call createOutputRow() to ensure that your output row’s Object[] is large
// enough to handle any new fields you are creating in this step.
r = createOutputRow(r, data.outputRowMeta.size());
/
TODO: Your code here. (See Sample)
// Get the value from an input field
String foobar = get(Fields.In, “a_fieldname”).getString®;
foobar += “bar”;
// Set a value in a new output field
get(Fields.Out, “output_fieldname”).setValue(r, foobar);
*/
// Send the row on to the next step.
putRow(data.outputRowMeta, r);
return true;

几个关键的地方
输入流中取出你上级传入的字段内容用

String foobar = get(Fields.In, “a_fieldname”).getString®;

a_fieldname是你上级输入的字段名
如果想改变你上级输入的内容的话,用这个

get(Fields.Out, “output_fieldname”).setValue(r, foobar);

其中:
output_fieldname是你要改变的内容的字段名
foobar:需要重写的内容
通过这两种方式:

get(Fields.In, “a_fieldname”).getString ( r);

get(Fields.Out, “output_fieldname”).setValue(r, foobar);

就可以改变你要传进来的内容并向下级输出。

如果是文件流的话看这个:

/* TODO: Your code here. (Using info fields)
FieldHelper infoField = get(Fields.Info, “info_field_name”);
RowSet infoStream = findInfoRowSet(“info_stream_tag”);
Object[] infoRow = null;
int infoRowCount = 0;
// Read all rows from info step before calling getRow() method, which returns first row from any
// input rowset. As rowMeta for info and input steps varies getRow() can lead to errors.
while((infoRow = getRowFrom(infoStream)) != null)
// do something with info data
infoRowCount++;

其实,当你点击main方法的时候,简单的使用他们注释上都有。

对了还有日志,这个是打印在控制台上的,下面就是:

点击logBasic就会出现

logBasic(msg);

这个就是日志。

02 升级使用

kettle里面本身自带的jar包对于有些稍微复杂的逻辑来说,
好多api都不可以使用,这种时候我们可以把我们需要的jar或者是我们自己项目打成jar包放入
\\data-integration\\lib文件下,记得要重启kettle。

比如,我这边需要一个json转换的方法,我就自己开了一个项目,将公用方法写进这个项目里打成jar包,放入lib文件下,使用的时候在java脚本里直接引用就好了。

看下面这个例子:

import com.tool.utils.XXX;
import java.text.ParseException;
import java.util.Date;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
public void initData(Object[] r )
  //初始化

public static final String TIME_LINE = "yyyy-MM-dd'T'HH:mm:ss.SSSXX";
    public static Date stringToDate(String date, String format)       throws  ParseException 
            DateFormat dateFormat = new SimpleDateFormat(format);
            dateFormat.setLenient(false);
            return dateFormat.parse(date);
    

public boolean processRow(StepMetaInterface smi, StepDataInterface sdi) throws  KettleExceptionParseException
  if (first) 
    first = false;
    
  
  Object[] r = getRow();
  if (r == null) 
    setOutputDone();
    return false;
  
  initData(r );
  r = createOutputRow(r, data.outputRowMeta.size());
  String yyy= get(Fields.In, "yyy").getString(r);
  //自定义里面的方法
  String ppp = new XXX().jsonToData(yyy);
  //重写
  get(Fields.Out, "yyy").setValue(r,ppp);
  putRow(data.outputRowMeta, r);
  return true;

语法跟java一样

引用就是import。
在这里你就把它当成java一个类就可以,没有jar包的就把jar包放入lib文件夹下,
在重启kettle就可以了。

以上是关于iOS-dispatch_semaphore的使用的主要内容,如果未能解决你的问题,请参考以下文章

使用“使用严格”作为“使用强”的备份

在使用加载数据流步骤的猪中,使用(使用 PigStorage)和不使用它有啥区别?

Sqlmap的使用

Kettle java脚本组件的使用说明(简单使用升级使用)

PageHelp的使用getParameter的使用zpage-nav的使用QRcode的使用wxpay微信支付的使用jackson-xml数据的转换

hbs使用手册