在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)
如果有人有明确的解释,我会非常有兴趣听到它.谢谢.
我正在进行巡回演唱,我觉得除了并发之外,我对语言有很好的理解.
在幻灯片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) 严格别名会阻止我们使用不兼容的类型访问相同的内存位置.
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) 为什么以下代码变慢?慢一点我的意思是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) 在我的单元测试中,我使用EasyMock来创建模拟对象.在我的测试代码中,我有类似的东西
EasyMock.expect(mockObject.someMethod(anyObject())).andReturn(1.5);
Run Code Online (Sandbox Code Playgroud)
所以,现在EasyMock将接受任何电话someMethod().有没有办法获得传递给它的真正价值mockObject.someMethod(),或者我需要EasyMock.expect()为所有可能的情况编写声明?
我正在阅读Linux内核开发,第3版,以了解内核实现和设计.第5章是关于系统调用的.作者展示了使用SYSCALL_DEFINE0宏定义的系统调用声明的示例,在该特定示例中扩展为:
asmlinkage long sys_getpid(void)
Run Code Online (Sandbox Code Playgroud)
他进一步说:
[...]对于32位和64位系统之间的兼容性,定义为在用户空间中返回int的系统调用在内核中返回long.
他没有比这更深入,我不能完全理解为什么会这样.为什么使用long与32位和64位系统相关的?为什么我们不能回归平原int?
我的书(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)
该书说,将一行留到下一行是非法的.但我不明白为什么.
在几个线程中共享相同的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) 我正在阅读最近发布的The Go编程语言,到目前为止它一直是一种喜悦(Brian Kernighan是作者之一,无论如何我都不会期待任何其他事情).
我在第3章遇到了以下练习:
练习3.13
const尽可能紧凑地 写入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 的幂.
有任何想法吗?
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)