gpt4 book ai didi

c - 如何同步调用shell命令?

转载 作者:行者123 更新时间:2023-11-30 14:47:05 29 4
gpt4 key购买 nike

我正在尝试教 dwm 在每个标签(www、文件、音乐...)中打开适当的应用程序。在dwm.c中有一个名为view的函数,负责标签切换。

void
view(const Arg *arg)
{
if ((arg->ui & TAGMASK) == selmon->tagset[selmon->seltags])
return;
/* toggle sel tagset */
selmon->seltags ^= 1;
if (arg->ui & TAGMASK)
selmon->tagset[selmon->seltags] = arg->ui & TAGMASK;

// user specific edit
prepareTag(arg->ui);

focus(NULL);
arrange(selmon);
}

我添加了一行调用 prepareTag 的位置。该函数具有简单的逻辑,除了一些验证(应用程序是否已打开?;它是什么标签?)和应用程序本身生成之外,什么也不做。

void
spawn(const Arg *arg)
{
if (arg->v == dmenucmd)
dmenumon[0] = '0' + selmon->num;
if (fork() == 0) {
if (dpy)
close(ConnectionNumber(dpy));
setsid();
execvp(((char **)arg->v)[0], (char **)arg->v);
fprintf(stderr, "dwm: execvp %s", ((char **)arg->v)[0]);
perror(" failed");
exit(EXIT_SUCCESS);
}
}

它可以工作,但代码是异步执行的。标签已更改,我看到了壁纸,大约 20-50 毫秒后应用程序启动。它会导致明显的闪烁。问题是我从未使用过 C,并且不知道代码异步工作的原因。我尝试过使用 system 函数而不是内置 spawn 函数,但 dwm 无法捕获以这种方式打开的应用程序。我可能可以使用 key Binder 和一些 BASHing,但方式相当肮脏。更不用说,我希望能够使用鼠标按钮来更改标签。

以防有人需要代码库。

git clone https://git.suckless.org/dwm

最佳答案

如果您阅读 fork() 的手册,您将意识到它创建了正在运行的进程的副本。

fork 后,两个进程彼此独立,并且可以按任何顺序进行调度。这就是您所看到的异步行为。

要获得同步行为,您的父进程需要等待 fork 进程完成(退出)。这是使用 wait() 实现的系统调用。

您可以将 spawn 函数修改为 -

void
spawn(const Arg *arg)
{
if (arg->v == dmenucmd)
dmenumon[0] = '0' + selmon->num;
if (fork() == 0) {
if (dpy)
close(ConnectionNumber(dpy));
setsid();
execvp(((char **)arg->v)[0], (char **)arg->v);
fprintf(stderr, "dwm: execvp %s", ((char **)arg->v)[0]);
perror(" failed");
exit(EXIT_SUCCESS);
} else { // fork returns a non zero pid in the parent process. So the else branch will be taken only in the parent.
wait(NULL); // Wait for the child process to change state. In this case exit
}
}

关于c - 如何同步调用shell命令?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51619556/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com