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
系列中的所有函数都会销毁当前进程中的所有线程,并将整个进程替换为您正在使用的进程exec
ing。
如果你想产生一个子进程,你仍然需要使用传统的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 <pthread.h>
。之后,编译器会告诉你有问题:
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的主要内容,如果未能解决你的问题,请参考以下文章