20、以下代码的作用是什么?在什么情况下可能会有用?childPid = fork(); if (childPid == -1) errExit(“fork1”); if (childPid == 0) { / Child / switch (fork()) { case -1: errExit(“fork2”); case 0: / Grandchild / / ----- Do real work here ----- / exit(EXIT_SUCCESS); / After doing real work / default: exit(EXIT_SUCCESS); / Make grandchild an orphan / } } / Parent falls through to here / if (waitpid(childPid, &status, 0) == -1) errExit(“waitpid”); / Parent carries on to do other things /
## 代码作用
创建一个子进程,子进程再创建一个孙进程,孙进程执行实际工作,子进程退出使孙进程成为孤儿进程,由系统收养,父进程等待子进程退出后继续执行其他任务。
## 适用情况
当需要在后台执行一些长时间的工作,且不想让父进程一直等待时,可使用此代码结构。比如后台数据处理、日志记录等任务。
21、当我们运行以下程序时,发现它没有输出。为什么会这样?#include int main(int argc, char argv[]) { printf(“Hello world”); execlp(“sleep”, “sleep”, “0”, (char ) NULL);}
printf 函数输出的内容通常会先被缓冲,而 execlp 函数会用新程序替换当前进程的映像,在替换之前缓冲内容未被刷新输出,所以看不到 printf 的输出。
22、除了缺少错误检查以及各种变量和结构声明外,以下程序有什么问题?static void * threadFunc(void arg) { struct someStruct pbuf = (struct someStruct ) arg; / Do some work with structure pointed to by ‘pbuf’ / } int main(int argc, char argv[]) { struct someStruct buf; pthread_create(&thr, NULL, threadFunc, (void *) &buf); pthread_exit(NULL); }
在 main 函数中, buf 是一个局部变量,存储在栈上。当 main 函数调用 pthread_exit 时, main 函数的栈帧会被销毁, buf 的内存也会被释放。而新创建的线程 threadFunc 可能还在使用指向 buf 的指针 pbuf ,这会导致线程访问已经释放的内存,产生未定义行为。
23、编写一个多线程程序,使线程启动函数中的每个循环输出全局变量 glob 的当前值和一个能唯一标识该线程的标识符。线程的唯一标识符可以作为创建线程时 pthread_create() 调用的参数。这需要将线程启动函数的参数改为一个指向包含唯一标识符和循环次数限制值的结构体的指针。运行该程序,将输出重定向到一个文件,然后检查文件,查看当内核调度器在两个线程之间交替执行时,全局变量 glob 会发生什么变化。
以下是修改后的代码示例:
#include <pthread.h>
#include "tlpi_hdr.h"
static int glob = 0;
// 定义包含唯一标识符和循环次数的结构体
typedef struct {
int id;
int loops;
} ThreadArgs;
static void * /* Loop 'arg' times incrementing 'glob' */
threadFunc(void *arg)
{
ThreadArgs *args = (ThreadArgs *)arg;
int loc, j;
for (j = 0; j < args->loops; j++) {
loc = glob;
loc++;
glob = loc;
// 输出当前线程的唯一标识符和glob的值
printf("Thread %d: glob = %d\n", args->id, glob);
}
return NULL;
}
int
main(int argc, char *argv[])
{
pthread_t t1, t2;
int s;
// 初始化结构体
ThreadArgs args1 = {1, (argc > 1) ? getInt(argv[1], GN_GT_0, "num-loops") : 10000000};
ThreadArgs args2 = {2, (argc > 1) ? getInt(argv[1], GN_GT_0, "num-loops") : 10000000};
s = pthread_create(&t1, NULL, threadFunc, &args1);
if (s != 0)
errExitEN(s, "pthread_create");


77

被折叠的 条评论
为什么被折叠?



