SBCL中用于多线程的原子操作

时间:2019-03-08 00:27:44

标签: multithreading common-lisp sbcl

加载包含原子操作的函数时出现错误。作为一个简单的示例,文件test.lisp包含:

export class Xxx {
  y: number;
  x: string;
}




private uploadFile(
    blobService: IBlobService,
    sasToken: ISasToken,
    file: File,
    options: { blockSize: number }
  ): Observable<Xxx> {
    return new Observable<Xxx>(observer => {
      const speedSummary = blobService.createBlockBlobFromBrowserFile(
        sasToken.container,
        sasToken.filename,
        file,
        options,
        error => this.callback(error, observer)
      );
      speedSummary.on('progress', () => this.getProgress(speedSummary, observer, sasToken.filename));
    }).pipe(
      startWith(0),
      distinctUntilChanged(),
      retry(4)
    );
  }

  private getProgress(speedSummary: ISpeedSummary, observer: Subscriber<Xxx>, fileName: string): void {
    const progress = parseInt(speedSummary.getCompletePercent(2), 10);
    // observer.next(progress === 100 ? 99 : progress);
    observer.next(new Xxx());
  }

  private callback(error: any, observer: Subscriber<Xxx>): void {
    if (error) {
      console.log(error);
      observer.error(error);
    } else {
      // observer.next(100);
      observer.next(new Xxx());
      observer.complete();
    }
  }

会产生以下错误:

(defparameter *count* 0)
(defun test ()
  (sb-ext:atomic-incf *count*))

* (load "d:\\test.lisp") ; file: d:/test.lisp ; in: DEFUN TEST ; (ATOMIC-INCF *COUNT*) ; ; caught ERROR: ; during macroexpansion of (ATOMIC-INCF *COUNT*). Use *BREAK-ON-SIGNALS* to ; intercept. ; ; Invalid first argument to ATOMIC-INCF: *COUNT* ; ; compilation unit finished ; caught 1 ERROR condition T * 为什么无效?

1 个答案:

答案 0 :(得分:3)

来自文档字符串:

PLACE must access one of the following:
 - a DEFSTRUCT slot with declared type (UNSIGNED-BYTE 64)
   or AREF of a (SIMPLE-ARRAY (UNSIGNED-BYTE 64) (*))
   The type SB-EXT:WORD can be used for these purposes.
 - CAR or CDR (respectively FIRST or REST) of a CONS.
 - a variable defined using DEFGLOBAL with a proclaimed type of FIXNUM.
Macroexpansion is performed on PLACE before expanding ATOMIC-INCF.

我怀疑这些是为了避免在进行比较和交换时进行运行时检查。