pthread并在C中递归调用execvp

Posted

技术标签:

【中文标题】pthread并在C中递归调用execvp【英文标题】:pthread and recursively calling execvp in C 【发布时间】:2011-11-12 17:21:51 【问题描述】:

首先我很抱歉我的英语:)

我正在寻找一种方法来在我的程序每次找到目录时创建一个线程,以便调用程序本身但使用新的 argv[2] 参数(即当前目录)。我用 fork() 成功地做到了,但是用 pthread 我遇到了一些困难。我不知道我是否可以这样做:

#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/wait.h>
#include <dirent.h>


int main(int argc, char **argv) 


    pthread_t  threadID[10] = 0;
    DIR * dir;
    struct dirent * entry;
    struct stat status;
    pthread_attr_t attr;
pthread_attr_init(&attr);

int i = 0;
char *res;
char *tmp; 
char *file;

 if(argc != 3)

    printf("Usage : %s <file> <dir>\n", argv[0]);
    exit(EXIT_FAILURE);



 if(stat(argv[2],&status) == 0)
 
    dir = opendir(argv[2]);
    file = argv[1];
 
 else
    exit(EXIT_FAILURE);

while ((entry = readdir(dir))) 


  if (strcmp(entry->d_name, ".") && strcmp(entry->d_name, ".."))


  tmp = malloc(strlen(argv[2]) + strlen(entry->d_name) + 2);

  strcpy(tmp, argv[2]);
  strcat(tmp, "/");
      strcat(tmp, entry->d_name);
  stat(tmp, &status);

  if (S_ISDIR(status.st_mode))
       

    argv[2] = tmp; 
    pthread_create( &threadID[i], &attr, execvp(argv[0], argv), NULL);

    printf("New thread created : %d", i);
    i++;

   
   else if (!strcmp(entry->d_name, file))
   
        printf(" %s was found - Thread number = %d\n",tmp, i);
        break;
    

    free(tmp);
  





pthread_join( threadID[i] , &res );

exit(EXIT_SUCCESS);



实际上它不起作用: pthread_create(&threadID[i], &attr, execvp(argv[0], argv), NULL);

我没有运行时错误,但是当要查找的文件在另一个目录中时,未创建线程,因此未调用 execvp(argv[0], argv)...

感谢您的帮助,

西蒙

【问题讨论】:

您的 pthread_create() 行甚至不应该编译。即使这样做,它也不会在创建的线程中运行 execvp。 这样删除你的问题内容是不礼貌的,因为这篇文章不仅为你服务,也为以后通过搜索找到它的任何人服务。 如果您希望将此内容与您的帐户解除关联,请标记此帖子。请不要再回滚了,它可能对其他人有帮助。 【参考方案1】:

从新线程调用execvp 毫无意义——exec 系列中的所有函数都会销毁当前进程中的所有线程,并将整个进程替换为您正在使用的进程execing。

如果你想产生一个子进程,你仍然需要使用传统的fork()/exec() 组合。请注意,您 fork 的子进程通常只有一个线程(称为 fork() 的那个),因此您无需过多担心其他线程在做什么。

【讨论】:

【参考方案2】:

首先,这不可能工作

想一想:execve 系统调用用一个新进程替换了当前进程(以及其中的所有线程)。如果您成功创建了第一个线程,那么一旦第一个线程到达execve,您的主线程就会立即消失。

其次,pthread_create 需要一个函数指针作为第三个参数。但是您传递的是这个表达式:execvp(argv[0], argv)。该表达式(在评估时)有什么作用?

它将您当前的流程替换为新流程!

您应该使用-Wall 构建您的代码,并修复所有警告。

按原样构建代码会导致:

gcc -c t.c -Wall
t.c: In function ‘main’:
t.c:18: warning: implicit declaration of function ‘pthread_attr_init’
t.c:55: warning: implicit declaration of function ‘pthread_create’
t.c:70: warning: implicit declaration of function ‘pthread_join’

这很容易解决,只需添加缺少的#include &lt;pthread.h&gt;。之后,编译器会告诉你有问题:

gcc -c t.c -Wall
t.c: In function ‘main’:
t.c:56: warning: passing argument 3 of ‘pthread_create’ makes pointer from integer without a cast
/usr/include/pthread.h:227: note: expected ‘void * (*)(void *)’ but argument is of type ‘int’
t.c:71: warning: passing argument 2 of ‘pthread_join’ from incompatible pointer type
/usr/include/pthread.h:244: note: expected ‘void **’ but argument is of type ‘char **’

【讨论】:

以上是关于pthread并在C中递归调用execvp的主要内容,如果未能解决你的问题,请参考以下文章

在C语言中用递归调用的方法求n!

matlab 递归调用例子

函数嵌套和递归调用

讲一下c语言中递归函数的使用方法有哪些?

main函数可否进行递归调用

C语言编程:用函数递归法求Fibonacci数列的前n项·