这是一个经典的 c/p 问题,其中一些线程生成数据而其他线程读取数据。生产者和消费者都共享一个常量大小的缓冲区。如果缓冲区为空,则消费者必须等待,如果缓冲区已满,则生产者必须等待。我正在使用信号量来跟踪已满或空的队列。生产者将减少空闲位置信号量,增加值,并增加填充槽信号量。所以我试图实现一个程序,从生成器函数中获取一些数字,然后打印出这些数字的平均值。通过将此视为生产者-消费者问题,我试图在程序执行中节省一些时间。generateNumber 函数会导致过程中出现一些延迟,因此我想创建多个生成数字的线程,并将它们放入队列中。然后是“主线程” 正在运行的主函数必须从队列中读取并找到总和,然后求平均值。所以这是我到目前为止所拥有的:
#include <cstdio>
#include <cstdlib>
#include <time.h>
#include "Thread.h"
#include <queue>
int generateNumber() {
int delayms = rand() / (float) RAND_MAX * 400.f + 200;
int result = rand() / (float) RAND_MAX * 20;
struct timespec ts;
ts.tv_sec = 0;
ts.tv_nsec = delayms * 1000000;
nanosleep(&ts, NULL);
return result; }
struct threadarg {
Semaphore filled(0);
Semaphore empty(n);
std::queue<int> q; };
void* threadfunc(void *arg) {
threadarg *targp = (threadarg *) arg;
threadarg &targ = *targp;
while (targ.empty.value() …
Run Code Online (Sandbox Code Playgroud) 目标:unfold
仅使用两个参数实现函数.
论点:
这是我到目前为止,我不知道为什么它不起作用:
(define (descending i)
(if (= i 0)
(list)
(cons i (- i 1))))
(define nil (list))
(define (unfold f init)
(if (eq? (f init) '())
(list)
(cons init (unfold f (f init)))))
(unfold (descending 5))
Run Code Online (Sandbox Code Playgroud)
应该评估
'(5 4 3 2 1)
Run Code Online (Sandbox Code Playgroud)
这应该是结果,但事实并非如此.我究竟做错了什么?
因此,查找列表中的最大元素需要O(n)时间复杂度(如果列表具有n个元素).我试图实现一个看起来更快的算法.
(define (clever-max lst)
(define (odd-half a-list)
(cond ((null? a-list) (list))
((null? (cdr a-list))
(cons (car a-list) (list)))
(else
(cons (car a-list)
(odd-half (cdr (cdr a-list)))))))
(define (even-half a-list)
(if (null? a-list)
(list)
(odd-half (cdr a-list))))
(cond ((null? lst) (error "no elements in list!"))
((null? (cdr lst)) (car lst))
(else
(let ((l1 (even-half lst))
(l2 (odd-half lst)))
(max (clever-max l1) (clever-max l2))))))
Run Code Online (Sandbox Code Playgroud)
这实际上更快吗?!你会说渐近时间复杂度是什么(紧束缚)?
complexity-theory scheme time-complexity asymptotic-complexity racket
我发现了以下汇编代码,我不知道它应该做什么(主要是因为cmovg遵循movl指令):
pushl %ebp
movl %esp, %ebp
movl 8(%ebp), %edx
movl %edx, %eax
sarl $31, %eax
testl %edx, %edx
movl $1, %edx
cmovg %edx, %eax
popl %ebp
ret
Run Code Online (Sandbox Code Playgroud)
所以这就是我到目前为止解释它的方式:推进堆栈
新指针(堆栈指针)创建指向与基指针相同的位置
获取输入(让我们称之为x)
将x复制到寄存器%eax(res = x)
res = res >> 31符号扩展名
测试x
设置x = 1
if>,res = x
恢复指针
返回res
但是,我不确定这个子程序的意义是什么.对我来说似乎毫无用处.如果你能指出这里做了什么,我将不胜感激.