开始我很抱歉我的英语:)
我想找到一种方法在每次程序找到一个目录时创建一个线程,以便调用程序本身但是使用新的argv [2]参数(这是当前的dir)。我用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(&amp; threadID [i],&amp; attr,execvp(argv [0],argv),NULL);
我没有运行时错误,但是当要查找的文件位于另一个目录中时,未创建该线程,因此不会调用execvp(argv [0],argv)......
谢谢你的帮助,
西蒙
答案 0 :(得分:6)
从新线程调用execvp
是没有意义的 - exec
系列中的所有函数都将销毁当前进程中的所有线程,并将整个事务替换为您{{1}的进程} ING。
如果您想要生成子流程,您仍需要使用传统的exec
/ fork()
组合。请注意,您分叉的子进程通常只有一个线程(调用exec()
的线程),因此您不必过于担心其他线程正在做什么。
答案 1 :(得分:3)
首先,这个无法正常工作。
考虑一下: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 **’