找回密码
 注册
查看: 1339|回复: 13

execl执行程序需要多久?

[复制链接]
发表于 2005-10-12 14:10:04 | 显示全部楼层 |阅读模式
我有一个图形界面的应用程序,运行时会有一个help button,点击button时,会执行下面的代码。开启如mozilla之类的browser,显示help信息。

但是在点击help button时,如果help browser应用没有处于打开状态,mozilla运行起来的速度很慢。特别是在这个应用程序运行起来后,第一次点击help button,需要等待较长的时间help的mozilla界面才能显示。

请问:这是什么原因?是什么造成了这个延迟?

if ((pid = fork ()) < 0) {
perror ("fork");
exit (1);
} else if (pid == 0) { /* child process */
int fd = open ("/dev/null", O_WRONLY);
if (fd < 0) {
perror ("open /dev/null");
} else {
if (dup2 (fd, 1) < 0 || dup2 (fd, 2)) {
perror ("dup2");
}
}
execl (help_browser,
help_browser,
helppage_path,
NULL);
}
这段程序应该是这样的,先fork一个进程,在执行execl。

程序在运行时,如果是第一次点击help button,需要等待的时间很难计算,有时候很久都不能打开help browser,需要点击2、3次才能打开。

请问这个等待是什么原因?
发表于 2005-10-12 15:16:19 | 显示全部楼层
直接system更省事。
mozilla本来就不是很快。
回复

使用道具 举报

 楼主| 发表于 2005-10-12 16:11:24 | 显示全部楼层
能说得更具体一些吗?
我是初次做linux下的编程,并不擅长。

再次谢谢了!
回复

使用道具 举报

发表于 2005-10-12 17:11:57 | 显示全部楼层
那你就用execl吧。
启动速度跟execl没有关系。
回复

使用道具 举报

 楼主| 发表于 2005-10-13 09:27:51 | 显示全部楼层
那是和fork()有关吗?

这个问题有没有方法解决?
回复

使用道具 举报

发表于 2005-10-13 10:46:56 | 显示全部楼层
是mozilla的问题,跟fork没有关系。
回复

使用道具 举报

发表于 2005-10-13 11:20:31 | 显示全部楼层
哈哈,先笑一下楼上版主老兄的名字和回复……

Mozilla 作为一个大型的应用程序,除了执行文件本身,还动态链接到许多的库;而且 Mozilla 自己实现了一套组件机制叫 XPCOM。加载动态库、启用 XPCOM 的时候都可能会有许多我们看不见的工作在进行,这些工作可能占据了非常多的时间。fork + exec 只是一个瞬间的事情,就像神六进入轨道开始离心运动只是一刹那的事情——但是之前的准备工作可能需要很多时间。

一个参考:
http://www.suse.de/~bastian/Export/linking.txt
回复

使用道具 举报

 楼主| 发表于 2005-10-13 13:02:44 | 显示全部楼层
我还想再问一下:

我在系统里面单独开启一个mozilla,大致看了一下时间需要4~5秒。
但是我的应用程序在启动之后从未使用help button的前提下,点击help button之后,需要等待很长时间。目前看起来,至少要点击2~3次才能开启mozilla。

但是第一次打开help 的mozilla界面之后(并且被关闭),后面再次点击help button,mozilla开启的速度就比较正常了。

我在程序里加了一些语句,看了一下时间:
int exRet = 0;
cur_time = time(NULL);
strncpy (buffer, ctime(&cur_time),24);
printf("begin to fork() %s \n", buffer);//current time

if ((pid = fork ()) < 0) {
perror ("fork");
exit (1);
} else if (pid == 0) { /* child process */
int fd = open ("/dev/null", O_WRONLY);
if (fd < 0) {
perror ("open /dev/null");
} else {
if (dup2 (fd, 1) < 0 || dup2 (fd, 2)) {
perror ("dup2");
}
}

exRet = //return value of execl
execl (help_browser,
help_browser,
helppage_path,
NULL);
}

cur_time = time(NULL);
strncpy (buffer, ctime(&cur_time),24);
printf(" %s return %d \n", buffer, exRet);

得到的结果是:
begin to fork() Thu Oct 13 10:43:16 2005
Thu Oct 13 10:43:16 2005 return 0 //mozilla没有反应
begin to fork() Thu Oct 13 10:44:12 2005
Thu Oct 13 10:44:12 2005 return 0 //mozilla没有反应
begin to fork() Thu Oct 13 10:44:42 2005
Thu Oct 13 10:44:42 2005 return 0 //mozilla被打开

请问为什么第一次调用mozilla会有那么长的时间?甚至点击一次在等待1-2分钟的时间后都没有响应?单独开启一个mozilla的应用看起来并不需要这么久的时间。
回复

使用道具 举报

发表于 2005-10-13 14:27:15 | 显示全部楼层
我在gtk里试的,我觉得你的execl放的位置不对
[code:1]
int fork2()
{
    pid_t pid;
    int status;

    if ((pid = fork()) == 0)
    {
        switch (fork())
        {
            case 0:
                return 0;
            case -1:
                _exit(-1);
            default:
                _exit(0);
        }
    }

    if (pid < 0 || waitpid(pid, &status, 0) < 0)
        return -1;

    return 1;
}

void
on_button1_clicked                     (GtkButton       *button,
                                        gpointer         user_data)
{
    if(fork2()==0)
    {
        system("firefox");
        gtk_main_quit();
    }
}

[/code:1]
回复

使用道具 举报

 楼主| 发表于 2005-10-13 17:13:45 | 显示全部楼层
你说得对,我的execl位置看起来不对,已经改过来了。

我重新测了一下,发现它的规律是:如果两次点击的时间间隔非常短,mozilla启动的速度就比较快。如果时间间隔很长,即便不是应用程序启动以后第一次点击help button,mozilla启动的速度也很慢。前面描述的现象相同。

与父进程和子进程的“调度”有关吗?我看到书上说父进程和子进程的执行顺序是无序的。
我对Linux内核不了解,所以不知道是不是这个原因。
回复

使用道具 举报

发表于 2005-10-13 17:27:31 | 显示全部楼层
继续怀疑是 ld 的关系。加载启动 Mozilla 需要加载各种 so 并且进行符号的解析;一次加载之后,这些可能仍然留在交换空间中,因此第二次加载就会速度很快;如果第二次加载之前等待了一段时间,可能由于系统的内存分配策略导致这些 so 被从交换空间释放,这样再次加载就需要再次进行 load so -> 解析符号的过程。
回复

使用道具 举报

 楼主| 发表于 2005-10-13 17:35:32 | 显示全部楼层
我对内核不是很了解,不过你说的内存空间释放我可以理解。

请问:如果是这种情况的话,有什么方法能改善吗?
回复

使用道具 举报

发表于 2005-10-13 17:51:59 | 显示全部楼层
看看我的第一个回复中的参考文档吧…… ld 程序正在试图改进,对这些情况进行优化。
回复

使用道具 举报

 楼主| 发表于 2005-10-13 19:59:55 | 显示全部楼层
继续请教:

刚刚跟踪了一下fork以后的pid,发现点击help button 后没有打开mozilla的情况,虽然fork成功,也获得了子进程的pid,但是/proc/下面并没有相应进程的目录及其相应的文件。当能打开mozilla时,相应的文件在/proc/就生成了。

请问这是什么原因?fork之后,子进程怎么了?

begin to fork() Thu Oct 13 19:37:23 2005
in child
child_pid 29551// 没有打开mozilla,也不存在/proc/29551
in parent
Thu Oct 13 19:37:24 2005 return 0
begin to fork() Thu Oct 13 19:38:23 2005
in child
child_pid 29597// 没有打开mozilla,也不存在/proc/29597
in parent
Thu Oct 13 19:38:24 2005 return 0
begin to fork() Thu Oct 13 19:39:00 2005
in child
child_pid 29627// 没有打开mozilla,也不存在/proc/29627
in parent
Thu Oct 13 19:39:01 2005 return 0
begin to fork() Thu Oct 13 19:39:30 2005
in child
child_pid 29654// 没有打开mozilla,也不存在/proc/29654
in parent
Thu Oct 13 19:39:31 2005 return 0
begin to fork() Thu Oct 13 19:39:56 2005
in child
child_pid 29678// 打开了mozilla,存在/proc/29678
in parent

代码如下:

{
1786 //DEBUG by Annie
1787 //
1788 char buffer[24];
1789 int exRet = 0;
1790 int status;
1791 time_t cur_time = time(NULL);
1792 strncpy (buffer, ctime(&cur_time),24);
1793 printf("begin to fork() %s \n", buffer);
1794
1795 pid = fork();
1796 if (pid < 0) {
1797 //if ((pid = fork ()) < 0) {
1798 perror ("fork");
1799 exit (1);
1800 } else if (pid == 0) { /* child process */
1801 puts("in child");
1802 printf("child_pid %d \n", getpid());
1803 int fd = open ("/dev/null", O_WRONLY);
1804 if (fd < 0) {
1805 perror ("open /dev/null");
1806
1807
1808 } else {
1809 if (dup2 (fd, 1) < 0 || dup2 (fd, 2)) {
1810 perror ("dup2");
1811
1812
1813 }
1814 //adjusted by Annie
1815 exRet =
1816 execl (help_browser,
1817 help_browser,
1818 helppage_path,
1819 NULL);
1820 }
1821 /*exRet =
1822 execl (help_browser,
1823 help_browser,
1824 helppage_path,
1825 NULL);*/
1826 //========================
1827 }
1828 //added by Annie
1829 else { /* parent process */
1830 puts("in parent");
1831
1832 }
1833 //========================
1834 //}
1835
1836 cur_time = time(NULL);
1837 strncpy (buffer, ctime(&cur_time),24);
1838 printf("%s return %d \n", buffer, exRet);
1839
1840 /* because set the handler of SIGCHLD to SIG_IGN,
1841 * here need not wait the exit of child process.
1842 * The child process will not become a zombie.
1843 */
1844
1845
1846 return;
1847
1848 }
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

GMT+8, 2025-2-7 20:15 , Processed in 0.030918 second(s), 15 queries .

© 2001-2025 Discuz! Team. Powered by Discuz! X3.5.

快速回复 返回顶部 返回列表