小编Fil*_*ves的帖子

如果分配了伪tty,为什么在ssh上运行后台任务会失败?

在ssh上运行命令时,我最近遇到了一些奇怪的行为.我有兴趣听到下面这种行为的任何解释.

正在运行ssh localhost 'touch foobar &'创建一个名为expect的文件foobar:

[bob@server ~]$ ssh localhost 'touch foobar &'
[bob@server ~]$ ls foobar
foobar
Run Code Online (Sandbox Code Playgroud)

但是,运行相同的命令但使用-t强制伪tty分配选项无法创建foobar:

[bob@server ~]$ ssh -t localhost 'touch foobar &'
Connection to localhost closed.
[bob@server ~]$ echo $?
0
[bob@server ~]$ ls foobar
ls: cannot access foobar: No such file or directory
Run Code Online (Sandbox Code Playgroud)

我目前的理论是,由于触摸过程正在被覆盖,因此伪进程在进程有机会运行之前被分配和未分配.当然,添加一秒睡眠可让触摸按预期运行:

[bob@pidora ~]$ ssh -t localhost 'touch foobar & sleep 1'
Connection to localhost closed.
[bob@pidora ~]$ ls foobar
foobar
Run Code Online (Sandbox Code Playgroud)

如果有人有明确的解释,我会非常有兴趣听到它.谢谢.

ssh bash jobs tty pty

17
推荐指数
1
解决办法
3557
查看次数

去游览履带式锻炼的麻烦

我正在进行巡回演唱,我觉得除了并发之外,我对语言有很好的理解.

幻灯片72上有一个练习,要求读者并行化一个网络爬虫(并使其不覆盖重复,但我还没有到那里.)

这是我到目前为止:

func Crawl(url string, depth int, fetcher Fetcher, ch chan string) {
    if depth <= 0 {
        return
    }

    body, urls, err := fetcher.Fetch(url)
    if err != nil {
        ch <- fmt.Sprintln(err)
        return
    }

    ch <- fmt.Sprintf("found: %s %q\n", url, body)
    for _, u := range urls {
        go Crawl(u, depth-1, fetcher, ch)
    }
}

func main() {
    ch := make(chan string, 100)
    go Crawl("http://golang.org/", 4, fetcher, ch)

    for i := range ch {
        fmt.Println(i)
    } …
Run Code Online (Sandbox Code Playgroud)

go

16
推荐指数
4
解决办法
7395
查看次数

严格的别名和内存位置

严格别名会阻止我们使用不兼容的类型访问相同的内存位置.

int* i = malloc( sizeof( int ) ) ;  //assuming sizeof( int ) >= sizeof( float )
*i = 123 ;
float* f = ( float* )i ;
*f = 3.14f ;
Run Code Online (Sandbox Code Playgroud)

根据C标准,这将是非法的,因为编译器"知道" 左值int不能访问float.

如果我使用该指针指向正确的内存,如下所示:

int* i = malloc( sizeof( int ) + sizeof( float ) + MAX_PAD ) ;
*i = 456 ;
Run Code Online (Sandbox Code Playgroud)

首先,我为内存分配内存int,float最后一部分是允许float存储在对齐地址的内存.float需要在4的倍数上对齐,MAX_PAD通常是16个字节中的8个,具体取决于系统.在任何情况下,MAX_PAD足够大,所以float可以正确对齐.

然后,我写的int进入i,到目前为止,一切顺利.

float* …
Run Code Online (Sandbox Code Playgroud)

c memory standards strict-aliasing

15
推荐指数
2
解决办法
1985
查看次数

如果在多个系统调用中完成,为什么TCP套接字会减慢?

为什么以下代码变慢?慢一点我的意思是100x-1000x慢.它只是直接在TCP套接字上重复执行读/写操作.奇怪的是,只有当我使用两个函数调用进行读取和写入时,它仍然很慢,如下所示.如果我更改服务器或客户端代码以使用单个函数调用(如在注释中),它将变得非常快.

代码段:

int main(...) {
  int sock = ...; // open TCP socket
  int i;
  char buf[100000];
  for(i=0;i<2000;++i)
  { if(amServer)
    { write(sock,buf,10);
      // read(sock,buf,20);
      read(sock,buf,10);
      read(sock,buf,10);
    }else
    { read(sock,buf,10);
      // write(sock,buf,20);
      write(sock,buf,10);
      write(sock,buf,10);
    }
  }
  close(sock);
}
Run Code Online (Sandbox Code Playgroud)

我们在一个更大的程序中偶然发现了这个,它实际上是使用stdio缓冲.当有效载荷大小超过缓冲区大小的那一刻,它神秘地变得缓慢.然后我做了一些挖掘strace,最后将问题归结为此.我可以通过愚弄缓冲策略来解决这个问题,但我真的很想知道这里到底发生了什么.在我的机器上,当我将两个读取呼叫更改为单个呼叫时,我的机器上的时间从0.030秒到超过一分钟(在本地和远程机器上测试).

这些测试是在各种Linux发行版和各种内核版本上完成的.结果相同.

具有网络样板的完全可运行的代码:

#include <netdb.h>
#include <stdbool.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <netinet/ip.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/tcp.h>

static int getsockaddr(const char* name,const char* port, struct sockaddr* res)
{
    struct addrinfo* list;
    if(getaddrinfo(name,port,NULL,&list) < 0) return …
Run Code Online (Sandbox Code Playgroud)

c sockets linux performance tcp

14
推荐指数
1
解决办法
4143
查看次数

EasyMock:获取EasyMock.anyObject()的真实参数值?

在我的单元测试中,我使用EasyMock来创建模拟对象.在我的测试代码中,我有类似的东西

EasyMock.expect(mockObject.someMethod(anyObject())).andReturn(1.5);
Run Code Online (Sandbox Code Playgroud)

所以,现在EasyMock将接受任何电话someMethod().有没有办法获得传递给它的真正价值mockObject.someMethod(),或者我需要EasyMock.expect()为所有可能的情况编写声明?

java unit-testing easymock

13
推荐指数
1
解决办法
2万
查看次数

为什么Linux系统调用返回类型为"long"?

我正在阅读Linux内核开发,第3版,以了解内核实现和设计.第5章是关于系统调用的.作者展示了使用SYSCALL_DEFINE0宏定义的系统调用声明的示例,在该特定示例中扩展为:

asmlinkage long sys_getpid(void)
Run Code Online (Sandbox Code Playgroud)

他进一步说:

[...]对于32位和64位系统之间的兼容性,定义为在用户空间中返回int的系统调用在内核中返回long.

他没有比这更深入,我不能完全理解为什么会这样.为什么使用long与32位和64位系统相关的?为什么我们不能回归平原int

c linux system-calls linux-kernel

12
推荐指数
1
解决办法
1916
查看次数

为什么在C中展平多维数组是非法的?

我的书(Kenneth Reek的C指针)说,以下是非法的,尽管它运作正常.

  int arr[5][5];
  int *p=&arr[2][2];
  p=p+3; // As array is stored in row major form I think this 
         //should make p point to arr[3][0]
Run Code Online (Sandbox Code Playgroud)

该书说,将一行留到下一行是非法的.但我不明白为什么.

c

10
推荐指数
2
解决办法
371
查看次数

可以在线程之间共享相同的epoll文件描述符吗?

在几个线程中共享相同的Epoll fd(不是socket fd)是否安全?如果是这样,每个线程是否必须将自己的事件数组传递给epoll_wait(2)它们,还是可以共享它?

例如

    void *thread_func(void *thread_args) {
      // extract socket_fd, epoll_fd, &event, &events_array from 
      //     thread_args
      // epoll_wait() using epoll_fd and events_array received from main
      // now all threads would be using same epoll_fd and events array 
    }

    void main( void ) {
      // create and bind to socket
      // create events_fd
      // allocate memory for events array
      // subscribe to events EPOLLIN and EPOLLET
      // pack the socket_fd, epoll_fd, &events, &events_array into 
      //   thread_args struct.

      // …
Run Code Online (Sandbox Code Playgroud)

c linux epoll pthreads

7
推荐指数
1
解决办法
2938
查看次数

将10的幂写为紧凑的常数

我正在阅读最近发布的The Go编程语言,到目前为止它一直是一种喜悦(Brian Kernighan是作者之一,无论如何我都不会期待任何其他事情).

我在第3章遇到了以下练习:

练习3.13const尽可能紧凑地 写入KB,MB,直到YB的声明.

(注意:在此上下文中,KB,MB等表示1000的幂)

这之前是一个iota作为有用的常量生成器机制引入的部分; 特别是,前一段显示了将1024的幂定义为常量的简洁方法:

const (
    _ = 1 << (10 * iota)
    KiB
    MiB
    GiB
    TiB
    PiB
    EiB
    ZiB
    YiB
)
Run Code Online (Sandbox Code Playgroud)

作者进一步提到了10的权力:

iota机制有其局限性.例如,由于没有取幂运算符,因此无法生成更熟悉的1000(KB,MB等)的幂.

我正在努力进行这项练习,因为看起来预期的解决方案比仅仅手动拼写1000的功能更为精细(特别是因为它出现之后iota).我觉得有一些聪明的方法可以用iota微妙的方式结合其他东西.

我想找到一种系统的方法来从1024的每个幂中减去"超额"量来获得1000的幂,但它让我无处可去.然后我查看二进制表示来尝试推断iota可能有用的一般模式,但同样,我什么也没得到.

我真的看不出如何在iota没有指数运算符的情况下从单个递增值()中产生1000 的幂.

有任何想法吗?

const go iota

7
推荐指数
2
解决办法
1345
查看次数

goto指令跳过可变长度数组

int main() {
    int sz = 10; 
    goto end;
    char bytes[sz];
end:
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

我在编译时遇到以下错误.我使用gcc和C99标准.

test.c: In function ‘main’:
test.c:3:2: error: jump into scope of identifier with variably modified type
test.c:5:1: note: label ‘end’ defined here
test.c:4:7: note: ‘bytes’ declared here
Run Code Online (Sandbox Code Playgroud)

c

6
推荐指数
1
解决办法
334
查看次数