存档

2013年10月 的存档

【翻译】创建并重定向子进程的标准输入输出

2013年10月14日 没有评论

原文地址:http://msdn.microsoft.com/en-us/library/windows/desktop/ms682499(v=vs.85).aspx
本节的实例描述了控制台进程如果通过CreateProcess函数创建子进程。同时展示了使用匿名管道重定向子进程的标准输入和标准输出句柄。当然,有名的管道也可以用来重定义进程的I/O。

CreatePipe函数使用SECURITY_ATTRIBUTES来创建可继承的读写端的管道。管道的读端作为子进程的标准输入,管道的写端作为子进程的标准输出。将这两个管道句柄设置到STARTUPINOF的结构体的标准句柄中(标准输入,标准输出,标准错误输出),这样子进程就可以继承这几个管道的句柄。

父进程使用管道的另外两端向子进程的标准输入中写入数据或者从子进程的标准输出读出数据。在STARTUPINFO结构体中,这些句柄(即父进程使用的另外两个句柄)也是可以承继的。然而这些句柄是不能被子进程继承(子进程中继承从标准输入中读取数据和向标准输出中写入数据)。因此,在创建子进程前,父进程调用SetHandleInfomation函数来保证向子进程标准输入中写入数据和从子进程标准输出中读出数据是不可以被继承的。更多信息,参阅Pipes。

下面的代码是的父进程的代码。它使用一个简单命令行参数:文本文件的名字。

下面是子进程的代码。它使用STDIN和STDOUT的继承句柄去访问父进程创建的管道。父进程从它的输入文件中读出并将读出的数据写到管道中。子进程通过过STDIN的管道读取数据和通过STDOUT的管道写入数据。父进程能过管道的读端读出数据并能过标准输出STDOUT显示出来。

本文还可以解决一个问题就是利用c库的system,_popen创建的进进程出现黑窗口的问题。另外原文件的父进程在创建子进程后增加了两行代码:

有点类似于pipe后,父进程关闭fd[1]子进程关闭fd[0]类似,这是子进程没有继承向子进程标准输入中写数据和向子进程标准输出读数据,因为父进程设置这两个句柄不可以继承。同时父进程也应该关闭自己的向子进程标准输入中读数据和向子进程中标准输出中写数据的句柄。

分类: 翻译 标签:

使用原子操作实现自旋锁

2013年10月14日 没有评论

原子操作
在windows平台有InterlockedCompareExchange原子操作接口。实现对内存的互斥修改

如果对函数的解释有点疑惑,可以看一下该函数的大致实现。

自旋锁
如果我们所1代表“加锁”,0代表“未加锁”。加锁的过程是将内存值0改成1,所以我们可以利用这特性实现加锁操作和解锁操作。

知道trylock只是尝试去将0改成1,如果之前已经是1说明,锁被占用了。所以我们实现了自旋等待锁被释放。

更好的实现,用Sleep切换CPU。

对于基于linux的gcc也是有相应的“比较修改”接口__sync_bool_compare_and_swap(lock, old, set),它的参数与windows的接口有两点不一样,参数不一致,返回类型也不一样。它的trylock的实现:

example

分类: C/C++, Linux, Win32 标签: