在 system() 内正确处理信号
我一直在阅读" Linux编程接口".第27章,程序执行. 我了解作者演示了我们如何使用exec和fork实现system呼叫.但是,具有挑战性的部分是处理信号.特别是我与以下文本感到困惑 要考虑的第一个信号是sigchld.假设程序 呼叫系统()也直接创造孩子,并且 为Sigchld建立了一个执行自己的等待()的处理程序.在 这种情况,当终止产生sigchld信号时 由System()创建的孩子的信号 主计划将被调用并收集孩子的 System()之前的状态有机会致电WaitPid(). (这是一 种族条件的示例.) 以下是没有信号处理的代码示例 #include #include #include int system(char *command) { int status; pid_t childPid; switch(childPid = fork()) {
6 2024-04-22
编程技术问答社区
如何从设备管理器获取信息?
在我的C#应用​​中,如何阅读有关设备的特定信息? 我尝试过WMI,但它没有提供我需要的信息. 我想要的信息存储在设备的详细信息选项卡中,以及我想要的信息"父". 我也看过康复,没有任何运气. 解决方案 Microsoft提供了一个样本: http://support.microsoft/a> 从C#中,捕获DevCon的输出可能比集成API更容易.如果您对此感到满意,那么C ++/CLI是迄今为止将设备信息输入.NET的最简单方法(我之前已经完成了). 其他解决方案 这些API应该让您前进: http://msdn.microsoft.com/en-us/library/ff550630(vs.85).aspx#retrieving_the_parent_of_a_a_device_inst 看起来Setupapi可以用作Windows Vista或更新的替代方案.以上方法可用于WIN2000+
2 2024-04-19
编程技术问答社区
执行家庭职能的工作
我正在研究Exec的功能家族.它的Man Page说,它用新的过程图像替换了当前的过程映像.如果它替换了二进制文件,则返回后,它如何获得该过程的先前参数,该过程称为exec?替换过程映像意味着替换其所有内存部分.如果我错了或较少知识,请纠正我. 解决方案 真正的作业由 execve(2) 系统通话.所有其他功能(例如execvp ...)都在调用execve. execve是一个相当复杂的系统调用. 成功时,它不会返回.但是流程状态(包括地址空间)已被完全改写. 基本上,地址空间变得新鲜.它包含来自二进制可执行文件的段. 程序参数,环境等...已被复制到新的地址空间中(在堆栈段的底部).因此,它们受到限制(ARG_MAX,通常为128kbytes-但是您可以通过重新编译内核来提高它. 地址空间更改实际上大部分是懒惰的(使用复制 );实际上,分页是无效的,随后的访问获得了页面错误,这是内核通过提供新页面等来提供的,等等. ... 在Linux上,我建议您
12 2024-04-10
编程技术问答社区
在子进程完成对FIFO的写入后,父进程如何读取该FIFO?
我有一个非常简单的基本程序,该程序具有两个进程是parent,第二个是child. 儿童过程应将一些东西写入FIFO.毕竟,所有写作工作都完成了(在孩子终止之后). 然后,父进程应读取所有FIFO文件并打印到stdout. 所以我想,我需要wait(NULL); wait(NULL); parent.因此,parent将等到child终止.但是,child也因写作而被阻止,并被阻止阅读此写作.因此,两个过程互相等待,我认为,发生了僵局. 我的程序是: #include #include #include #include #include #include #include #include int writeSomeStuffToFifo (); void pri
12 2024-04-10
编程技术问答社区
c fork,exec,getpid问题
我是C语言和Linux的新手.我有一个与fork(),getPid()和exec()函数有关的问题. 我使用fork()调用程序的代码写了一个C程序. 代码: #include #include #include #include void fun() { printf("\n this is trial for child process"); } int main (int argc, char const *argv[]) { int i,status,pid,t; if(pid=fork()
6 2024-04-09
编程技术问答社区
查找一个地址属于哪个页面
我可以在记忆中找到缓冲区的地址,如下所示: - int main() { char buffer[100]; printf("%p\n, buffer); } 有什么方法可以打印出缓冲区属于的页面的地址? [编辑] 我在Linux机器上,确切地说是Ubuntu.我对32位和64位版本都感到好奇. 解决方案 似乎没有Linux提供的系统调用,我们可以在其中获取此类信息.但是,我认为我们可以通过以下步骤获取信息(/proc目录): Get the buffer address assume 0x7fffffffe0b0(attach with gdb so that program would pause) Execute the command(cat /proc/3586/maps)assume PID = 3586 Execute the command(cat /proc/3586/numa_maps) 现在按照缓冲区地址属于下面的[堆栈]
2 2024-04-09
编程技术问答社区
当使用不同的文件描述符时,为什么结果会不同?(系统编程)
我正在研究文件描述,并意识到如果我使用dup2()函数, 结果将有所不同. 第一个片段... int main(void){ char buf1[BUFSIZ] = "I am low\n"; printf("i am high\n"); write(1, buf1, strlen(buf1)); write(1, buf1, strlen(buf1)); write(1, buf1, strlen(buf1)); return 0; } ...产生以下结果: i am high i am low i am low i am low 但是第二个片段... int main(void){ int fd = open("dupout",O_CREAT | O_WRONLY, 0655); char buf1[BUFSIZ] = "I am low\n"; dup2(fd, 1);
6 2024-04-09
编程技术问答社区
硬盘上的连续空间 | NTFS
我的问题是关于NTFS FS上的文件分配方法. 我有两个主要问题 - 当我在NTFS上创建文件时,是否连续存储在物理硬盘上? 如果不是 - 有没有办法创建一个文件,以便当我写入数据时,数据是连续存储的(在硬盘上)吗?类似数据库中的范围. 如果存在这样的文件 - 是否有任何方法可以从中读取数据(使用C读取系统调用) 束/块.我可以使用的最大束尺寸是多少. 我正在尝试为小型应用程序制作一个简单的基于文件的DB,并希望在文件中制作我的DB.出于性能原因,我需要在磁盘上保持数据的连续顺序,然后堆积. (我打算在我的应用程序中map此文件). 解决方案 好吧,所以让我们逐点回答... 问题1 :当我在NTFS上创建文件时,它是否连续存储在物理硬盘上? 这个问题没有意义.创建文件时,NTFS将为MFT中的空间分配用于跟踪事物所需的元数据.小文件实际上可能适合文件的MFT记录 - 从定义上讲,此类居民文件是连续的.如果文件不适用于MFT内,则根据需要分配空间块
2 2024-04-09
编程技术问答社区
opendir不接受字符串变量,但会接受普通字符串。
我无法使此功能正常工作,因为出于某种原因,Opendir不会将Buffer2(称为Char Buffer2 [128])作为一个参数正确.如果我将变量替换为"".或"样本",它可以很好地工作.但是这样做,我每次都会得到一个细分错误.请帮忙. system("clear"); DIR *dirp; struct dirent *dp; printf("Enter directory name: "); fgets(buffer2, 100, stdin); if((dirp = opendir(buffer2)) == NULL) printf("Could not open directory\n"); while((dp = readdir(dirp)) != NULL)
4 2024-04-09
编程技术问答社区
vfork()系统调用
我读到,使用vfork()系统呼叫创建的新过程是在父的地址空间中执行的线程,直到子螺纹do do do not call exit()或exec()系统调用,parent the parent herment n of the the parent herment n opent.所以我使用vfork()系统调用 编写了一个程序 #include #include int main() { pid_t pid; printf("Parent\n"); pid = vfork(); if(pid==0) { printf("Child\n"); } return 0; } 我的输出如下: Parent Child Parent Child Parent
10 2024-04-08
编程技术问答社区
如何指定向普通文件(不是管道或fifo)进行原子写入的标准?
POSIX标准指定的是,当写入小于pipe_buf字节或FIFO时,授予原子质,也就是说,我们的写入不会与其他过程混合.但是我未能找出标准规定的常规文件.我的意思是,当我们撰写少于pipe_buf时,它也将被授予原子.但是我想知道常规文件有这样的限制吗?我的意思是,管道具有容量,因此,当写信给管道并超出其容量之外,内核会使作者入睡,因此其他过程将有机会写作,但是常规文件似乎不必这样限制,我是吗? 我正在做的几个过程将日志生成文件.当然,使用O_Append集. 解决方案 引用/toc.htm (单个Unix规范,版本4,2010版): 这一卷的POSIX.1-2008并未指定并发从多个过程写入文件的行为.应用程序应使用某种形式的并发控制. 该规范确实解决了在多个读者的情况下如何出现关于写作的语义的语义,但是正如您可以从上面看到的那样,该规范未定义多个并发作者的行为. . 上面的注释文件.对于Pipe_max语义的应用,适用于Pipe_max的语义,并确保
6 2024-04-08
编程技术问答社区
叉子的实施
如何编写叉子系统呼叫代码.我想知道一些详细信息,一个函数如何返回两个不同的值并将两个值返回两个不同的过程.简而言之,想知道如何实现叉系统调用? 解决方案 卡尔的回答很棒.我想补充一点,在许多操作系统中,返回值都在其中一个寄存器中传递.在x86体系结构中,此寄存器可能是EAX,在ARM架构中,此寄存器可能是R0,等等. 每个过程还具有一个过程控制块(PCB),该过程在某些中断,SYSCALL或异常时存储寄存器的值,并且将控制传递给OS.下次进程计划时,寄存器的值将从PCB恢复. 现在,当叉()发生时,OS可以做: child_process->PCB[return_value_register] = 0; parrent_process->PCB[return_value_register] = child_pid; 因此,当重新安排过程时,每个过程都会看到不同的返回值. 作为一个例子,您可以看到// Clear %eax so that fork
8 2024-04-08
编程技术问答社区
C和C++的标准是否意味着在地址空间中必须存在一个特殊的值来代表空指针的值?
在讨论这个问题关于C和C ++中的无指针在这里. 如果可以从C和C ++标准(答案可以针对两个标准)推断出它,该指针变量等于nullptr(或(void *)0)值是未定义的行为,是否意味着这些暗示这些语言要求地址空间中的特殊值是 dead ,这意味着它是无法使用的,除了表示nullptr的作用?如果系统在等于nullptr的同一地址上具有真正有用的功能或数据结构怎么办?这是否永远不会发生,因为这是编译器的作者责任,弄清编译器编译为每个系统的不冲突的无空间指针值?或者,在"不确定行为模式"以实现其意图的过程中,需要访问此类功能或数据结构的程序员是内容? 这看起来像是模糊了编译器和计算机系统的角色的线条.我会问是否正确,但是我想这里没有空间. 解决方案 这是否意味着这些语言要求地址空间中的特殊价值已经死了,这意味着它是无法使用的,除了表示nullptr? 的作用 no. 编译器需要一个特殊的值来表示空指针,并且必须注意它不会在该地址放置任何对象或功能,因为
8 2024-04-07
编程技术问答社区
在C/C++中,直接写到一个内存地址的最短代码是什么?
我正在为无内存保护的嵌入式系统编写系统级代码(在ARM Cortex-M1上,使用GCC 4.3编译),需要直接读/写入内存映射的寄存器.到目前为止,我的代码看起来像这样: #define UART0 0x4000C000 #define UART0CTL (UART0 + 0x30) volatile unsigned int *p; p = UART0CTL; *p &= ~1; 是否有任何较短的方法(代码较短)不使用指针?我正在寻找一种像这样简短编写实际分配代码的方法(如果我必须使用更多#Defines,可以): *(UART0CTL) &= ~1; 我到目前为止尝试的任何事情最终都以GCC抱怨说,它无法分配给LVALUE ... 解决方案 我想成为一个nitpick:我们是在谈论C还是C ++? 如果C,我愿意屈服于克里斯的回答(我希望删除C ++标签). 如果C ++,我建议完全使用那些讨厌的C-Casts和#define.
2 2024-04-07
编程技术问答社区
我们必须使用C语言,"出于性能原因"
在多种语言的这个时代,似乎每项任务都有很棒的语言,我发现自己在专业地挣扎着" cop of c c fast "的咒语,其中快速就是真正打算表示"足够快".我与非常理性的开放式人一起工作,他们喜欢比较数字,而我所拥有的只是思想和观点.您能帮我找到自己的主观意见并进入"现实世界"的方式? 您会帮助我找到研究吗?我很可能会推出一个错误的假设,并非常感谢研究向我展示这一点.您能否请链接或包含好的数字,以帮助将"这只是他/她的意见"评论至少. 所以这些是我的特殊要求 记忆不是严重的约束 可移植性不是严重关注的问题 这不是实时系统 解决方案 "除了C很快[足够],"什么都没有"是一种早期的优化和错误,因为所有早期优化都是错误的.如果您的系统具有足够的复杂性,则需要除C以外的其他功能,那么系统的某些部分必须"足够快",并且部分具有较轻的约束.例如,如果编写您的代码,则在Python中,该项目的完成速度更快,错误,则可以使用一些C或汇编代码来加快关键时间的零件. .
12 2024-04-07
编程技术问答社区
如何在C语言中只列出第一级目录?
在端子中,我可以调用ls -d */.现在我想要一个#include #include #include #include int main( void ) { int status; char *args[] = { "/bin/ls", "-l", NULL }; if ( fork() == 0 ) execv( args[0], args ); else wait( &status ); return 0; } 这将ls -l一切.但是,当我尝试时: char *args[] = { "/bin/ls", "-d", "*/", NULL }; 我会得到一个运行时错误: ls: */:没有这样的文件或目录 解决方案 不幸的是,所有基于壳的扩展的解决方案都受到最大命令线长度的限制.哪个变化(运行true | xargs --show-limits以找出答案
10 2024-04-06
编程技术问答社区
如何在C语言中不使用POSIX库<pthread.h>来制作线程?
我想在C中实现多个线程,而无需使用任何POSIX库. 任何帮助将不胜感激. 不:不要使用fork()或vfork(). 解决方案 请参阅: setJmp , longjmp , sigaltstack , sigaltstack 对于Unix类似系统. 也请参见: getContext和setContext , 和更一般的 ucontext 用于BSD和现代Unixes. 这个 page 提供了许多使用这些原始剂等的准式示例. 您可以使用原子说明来实现锁定原语(Mutex,Semaphores). 我还建议您查看Userland线程库的实际实现以获取一些提示.请参阅此页面提供了Linux的实现列表. 最后,您可能想在 coroutines上获得一些信息=" http://en.m.wikipedia.org/wiki/wiki/trampoline_%28computing%29" rel =" noreferr
10 2024-04-06
编程技术问答社区
mmap on /proc/pid/mem
使用Linux内核2.6成功完成了mmap'ing a/proc/pid/mem文件?我正在遇到Enodev(没有这样的设备)错误.我的电话看起来像这样: char * map = mmap(NULL, PAGE_SIZE, PROT_READ, MAP_SHARED, mem_fd, offset); ,我已经通过查看/proc/pid/maps文件进行验证,当执行到达此调用时,偏移量具有堆栈降低page_size的值.我还用ptrace验证了mmap将errno设置为enodev. 解决方案 请参阅可以通过linux-source软件包安装revercitve linux内核来源,也可以通过直接从
4 2024-04-06
编程技术问答社区
如何制作一个守护进程
我试图了解如何使我的程序成为守护程序.因此,我遇到的某些事情通常是一个程序,一个程序执行以下步骤成为守护程序: 呼叫fork(). 在父母中,调用exit().这确保了原始父母(守护程序的 祖父母)满足对守护程序的父母否定的孩子的满意 越来越长的跑步,守护程序不是过程组的负责人.最后一点 是成功完成下一步的要求. 呼叫setsid(),给守护程序一个新的过程组和会话,这两个 作为领导者.这也确保该过程没有关联 控制终端(因为该过程刚刚创建了一个新会话,并且不会分配 一个). 通过chdir()将工作目录更改为根目录.这个做完了 因为继承的工作目录可以在文件系统上的任何位置. 守护程序往往会在系统的正常运行时间内运行,而您不想要 保持一些随机目录打开,从而阻止管理员 卸载包含该目录的文件系统. 关闭所有文件描述符. 打开文件描述符0、1和2(标准,标准输出和标准错误) 并将它们重定向到/dev/null. #include
10 2024-04-06
编程技术问答社区
C语言中叉子的工作原理
现在,我在理解fork()系统调用的工作方面有一个问题. 我编写了一个以下的代码: #include int main() { int a, b; b=fork(); printf("\n the value of b = %d",b); } 此代码的输出如下: 现在我不明白为什么输出是这样的? 之后,我只是在代码中添加一条线,输出完全不同. 我的代码如下: int main() { int a, b; b=fork(); 当我运行代码时,输​​出正在遵循 2389我的名字是Manish the value of b = 0 现在,我对fork()呼叫的工作完全感到困惑. 我的问题如下: fork()如何工作? fork()呼叫之后的控件进入何处? 任何身体都可以解释为什么编写问题的代码的输出? 为什么在不同地方出现b的输出在第一个代码中表示 b = 2260的输出就
4 2024-04-06
编程技术问答社区