标签: systems-programming

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

调用pthread_join()后的分段错误

我使用POSIX pthread库编写了以下代码:

#include<stdio.h>
#include<stdlib.h>
#include<pthread.h>

pthread_t pid1,pid2;

void *test(void *arg)
{
void **end;
printf("\nNew Thread ID: 0x%x\n",(unsigned int)pid2);
pthread_join(pid1,end);
printf("\nNew Thread going to go off\n");
printf("\nNew Thread ID: 0x%x\n",(unsigned int)pid2);
return ((void *)NULL);
}    

int main()
{
pid1 = pthread_self();
pthread_create(&pid2,NULL,test,NULL);
printf("\nMain Thread ID: 0x%x\n",(unsigned int)pid1);
sleep(2);
printf("\nI am going off\n");
pthread_exit(0);
}
Run Code Online (Sandbox Code Playgroud)

在执行代码时,我得到以下输出:

Main Thread ID: 0xb7880b30
New Thread ID: 0xb787eb70
I am going off
Segmentation fault

在我研究的时候,调用pthread_join的线程(pid2)将阻塞,直到在参数(pid1)中传递的线程调用pthread_exit().并且pthread_exit()用于停止执行特定线程,让所有其他线程继续执行.

我想知道为什么我最后会遇到Segmentation Fault.

请妥善解释一下.

c pthreads systems-programming

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

无法进入系统调用源代码

我用-g选项编译了我的freebsd libc源代码,现在我可以介入libc函数了.

但我无法进入系统调用代码.我用-g编译了freebsd内核源代码.在设置断点时,gdb会在.S文件上通知断点.在点击断点时,gdb无法进入系统调用源代码.

另外,我试过:gdb $ catch系统调用打开

但这也行不通.

你能建议一下吗?

谢谢.

unix gdb systems-programming

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

为什么使用 mmap 和 madvise 顺序逐行读取大文件比 fgets 慢?

概述

我有一个程序受 IO 限制,正在尝试加快速度。使用 mmap 似乎是一个好主意,但与仅使用一系列 fgets 调用相比,它实际上降低了性能。

一些演示代码

我已经将演示压缩到了基本要素,对一个 800mb 的文件进行了测试,大约有 350 万行:

使用 fgets:

char buf[4096];
FILE * fp = fopen(argv[1], "r");

while(fgets(buf, 4096, fp) != 0) {
    // do stuff
}
fclose(fp);
return 0;
Run Code Online (Sandbox Code Playgroud)

800mb 文件的运行时:

[juhani@xtest tests]$ time ./readfile /r/40/13479/14960 

real    0m25.614s
user    0m0.192s
sys 0m0.124s
Run Code Online (Sandbox Code Playgroud)

mmap 版本:

struct stat finfo;
int fh, len;
char * mem;
char * row, *end;
if(stat(argv[1], &finfo) == -1) return 0;
if((fh = open(argv[1], O_RDONLY)) == -1) return 0;

mem …
Run Code Online (Sandbox Code Playgroud)

c mmap systems-programming

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

vfork()系统调用中的返回值

考虑以下代码:

int main()
{
  int pid;
  pid=vfork();
  if(pid==0)
     printf("child\n");
  else
     printf("parent\n");
  return 0;
  }
Run Code Online (Sandbox Code Playgroud)

vfork()的情况下,父进程和子进程使用的地址空间是相同的,因此应该存在变量pid的单个副本.现在我无法理解这个pid变量如何具有vfork()返回的两个值,即,对于子项为零而对于父项为非零?

fork()的情况下,地址空间也被复制,每个子节点和父节点中都有两个pid变量副本,所以我可以理解在这种情况下,两个不同的副本可以有fork()返回的不同值,但是无法理解在vfork()的情况下,pid如何具有vfork()返回的两个值?

c operating-system system-calls systems-programming

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

使用sigaction(),c

我正在做一些阅读sigaction()(来自我的课程笔记),我不确定我理解这个文字:

仅在信号处理程序的持续时间内计算和安装信号掩码.

默认情况下,信号"sig"也会在信号出现时被阻止.

使用sigaction为特定信号安装操作后,它将一直安装,直到明确请求另一个操作.

这是否意味着在从信号处理程序返回后恢复默认信号掩码?另外,使用后我是否必须重新安装处理程序,就好像我在使用它一样signal()

还有,这段代码:

#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

void termination_handler(int signum) {
    exit(7);
}

int main (void) {
  struct sigaction new_action,old_action;
  new_action.sa_handler = termination_handler;
  sigemptyset(&new_action.sa_mask);
  sigaddset(&new_action.sa_mask, SIGTERM);
  new_action.sa_flags = 0;
  sigaction(SIGINT, NULL, &old_action);
  if (old_action.sa_handler != SIG_IGN) {
         sigaction(SIGINT,&new_action,NULL);
  }
  sleep(10);
  return 0;
}
Run Code Online (Sandbox Code Playgroud)

那么 - 究竟将如何SIGTERM处理?我可以看到安装的处理程序是termination handler(),但随后SIGTERM被添加到信号掩码而没有使用sigprocmask().这是什么意思?谢谢!

Ps最后一个问题:为什么if声明在main()

c unix signals bitmask systems-programming

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

linux execvp; ls无法访问|,没有这样的文件或目录

我正在尝试编写shell.但是我的shell没有执行命令 - ls -l | 减.我正在使用execvp.代码如下.

#include <stdio.h>
#include <unistd.h>
#include <string.h>

int main(){
    int pid, status, num, len;
    char str[1000], cwd[100];
    char* word[100];

    getcwd(cwd, sizeof(cwd));

    while(1){
        chdir(cwd);

        printf("%s > ", cwd);

        gets(str);

        pid=vfork();

        if(pid == 0){
            num = 0;
            word[num] = strtok (str, " ");

            while (word[num] != NULL) {
                word[num] = strdup (word[num]);
                len = strlen (word[num]);
                if (strlen (word[num]) > 0)
                    if (word[num][len-1] == '\n')
                        word[num][len-1] = '\0';
                word[++num] = strtok (NULL, " ");
            }

            if(strcmp(word[0], "cd") …
Run Code Online (Sandbox Code Playgroud)

c linux shell exec systems-programming

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

vfork()系统调用

我读到使用vfork()系统调用创建的新进程作为父地址空间中的线程执行,直到子线程不调用exit()或exec()系统调用,父进程被阻塞.所以我用vfork()系统调用编写了一个程序

#include <stdio.h>  
#include <unistd.h>

int main()  
 {  
      pid_t pid;  
      printf("Parent\n");  
      pid = vfork();  
      if(pid==0)  
      {  
          printf("Child\n");  
      }  
      return 0;  
  }
Run Code Online (Sandbox Code Playgroud)

我得到的输出如下:

 Parent  
 Child  
 Parent  
 Child  
 Parent  
 Child  
 ....  
 ....  
 ....
Run Code Online (Sandbox Code Playgroud)

我假设return语句必须在内部调用exit()系统调用,所以我只期望输出

Parent  
Child
Run Code Online (Sandbox Code Playgroud)

有人可以解释为什么实际上它不会停止并持续打印无限循环.

c fork systems-programming

5
推荐指数
1
解决办法
5884
查看次数

从C程序中调用调试器

我正在读大卫汉森的书"C接口和实现".这个练习题似乎很有趣,无法找到解决方案:

在某些系统上,程序在检测到错误时可以自行调用调试器.当断言失败可能很常见时,此工具在开发期间特别有用.

您能否提供一个关于如何调用调试器的简短示例.

void handle_seg_fault(int arg)
{
    /* how to invoke debugger from within here */
}

int main()
{
    int *ptr = NULL;
    signal(SIGSEGV, handle_seg_fault);
    /* generate segmentation fault */
    *ptr = 1;
}
Run Code Online (Sandbox Code Playgroud)

c linux gdb systems-programming

5
推荐指数
1
解决办法
266
查看次数

连接的USB设备的分类

我正在编写一个C#应用程序,用于监视和记录连接到Windows系统的不同USB设备.使用Window的设置API,我可以获得诸如VID,PID,硬件ID和友好名称等详细信息.我想问的是,在Windows中有一种方法可以检查连接的设备是SmartPhone,打印机,大容量存储设备还是调制解调器?

注意:使用SetupGerDeviceRegistryProperty()我能够获取设备描述,但是对于所有设备,它显示设备描述是USB复合设备.

usb winapi systems-programming winforms c#-4.0

5
推荐指数
1
解决办法
264
查看次数