收藏 分享(赏)

实验十七 Linux下进程线程的创建.ppt

上传人:11xg27ws 文档编号:10092900 上传时间:2019-10-09 格式:PPT 页数:25 大小:1.05MB
下载 相关 举报
实验十七 Linux下进程线程的创建.ppt_第1页
第1页 / 共25页
实验十七 Linux下进程线程的创建.ppt_第2页
第2页 / 共25页
实验十七 Linux下进程线程的创建.ppt_第3页
第3页 / 共25页
实验十七 Linux下进程线程的创建.ppt_第4页
第4页 / 共25页
实验十七 Linux下进程线程的创建.ppt_第5页
第5页 / 共25页
点击查看更多>>
资源描述

1、Linux下进程和线程的创建 吴国伟 学习 Linux中 创建进程 的方法 学习系统调用 Fork的使用方法 学习系统调用 Exec族 的使用方法 学习 Linux中 创建线程 的方法 学习 pthread_create使用方法 10/9/2019 PID: 进程号。 PPID: 父进程号。 UID: 其创建者的用户标识号,父子进程有相同的 UID值。 Linux进程创建 Linux进程的族亲关系 Linux进程之间不是孤立存在的,它们之间有一定的族亲关系。 一个进程的子进程可以多于一个。 一个进程只会有一个父进程。 进程 1 进程 2 父进程 子进程 产 生 Linux进程创建 系统加电启动

2、后,系统中只有一个进程 初始化进程 ,又称 init进程 ,是所有进程的祖先进程,它的进程 pid=1 在 linux中除了 init进程是由系统启动时创建的外,其他所有进程都是由当前进程使用系统调用 fork()创建的。 进程创建后父子进程在系统中 并发执行 。 进程结构 同时运行 grep程序,在不同文件中查找不同的字符串 PID 101 代码 数据 s=“one” 函数库 文件 Trek.txt PID 102 代码 数据 s=“two” 函数库 文件 Next.txt grep程序代码 C语言函数库 Fork()系统调用 此时一个进程“分裂”成两个进程:父进程和子进程。 区别:进程 I

3、D。利用 getpid()来得到进程号。 通过 fork创建一个新进程,系统复制当前进程,在进程表中创建一个新的表项 新进程几乎与原进程相同,执行代码也相同 但有自己的数据空间,环境,文件描述符等 #include pid_t fork( ); Fork()系统调用 fork调用的一个奇妙之处就是它仅仅被 调用一次 ,却能够 返回两次 ,它可能有三种不同的返回值: 父进程 :返回 子进程的 PID; 子进程 :返回 0; 出现 错误 :返回 -1; 最初的进程 fork() 原进程继续 执行 新进程 返回一个新的 pid 返回0 10/9/2019 #include #include #inc

4、lude int main() int pid = fork(); if (pid = -1 ) printf(“error!n“); else if( pid = 0 ) printf(“This is the child process!nchild process id = %dn“,getpid(); else printf(“This is the parent process!nparent process id = %dn“,getpid(); return 0; 10/9/2019 运行结果: This is the child process! child process i

5、d = 4800 This is the parent process! parent process id = 4799 Fork()系统调用 等待一个进程结束 #include #include pid_t wait(int *stat_loc) 父进程调用 1. wait系统调用将暂停父进程直到它的子进程结束为止 2. 返回子进程的 PID 3. 状态信息允许父进程了解子进程的退出状态,即子进程main函数返回值或子进程中 exit函数的退出码 4. 若 stat_loc不为空指针,状态信息被写入他指定的为止 10/9/2019 父进程创建子进程后 ,子进程一般要执行不同的程序 .为了调

6、用系统程序 ,我们可以使用系统调用exec 族调用。 Exec函数可以把当前进程替换为一个新进程 exec函数包含以下五个函数: #include int execl(constchar* path, const char* arg, ); int execlp(constchar* file, const char* arg, ); int execle(constchar* path, const char* arg, char* const envp); int execv(constchar* path, char* const argv); int execvp(constchar*

7、 file, char* const argv); 10/9/2019 其中只有 execve是真正意义上的系统调用,其它都是在此基础上经过包装的库函数。 #include intexecve(constchar* path, char* const argv, char* const envp); path:可执行文件路径。 argv:要执行的文件名或命令名。 envp:环境变量,可省略 Linux 创建线程 线程:一个进程内部的一个控制序列 每个进程都至少有一个执行线程 创建线程与 fork区别 fork: 当前进程的拷贝,有自己的变量和 PID,时间调度独立,执行几乎完全独立于父进程 新

8、线程: 有自己独立栈(有局部变量) 但与创建者共享全局变量,文件描述,信号句柄和当前状态等 线程优缺点 优点: 一般而言,线程创建以及线程之间的切换需要操作系统做的工作比进程少得多。 例子:编辑文档过程的多线程,一个线程负责用户输入和编辑,一个线程负责字数统计 缺点: 多线程程序因变量共享可能引发潜在错误,调试困难 pthread_creat int pthread_create( pthread_t *thread, pthread_attr_t *attr, void *(*start_routine)(void*), void *arg) 参数 1. 该指针指向的变量中将被写入一个标识符

9、,用该 标识符来引用新线程 2. 设置线程属性,一般不用设为 null 3. 表示线程将要启动执行的函数 4. 该函数需要的参数 调用成功返回值为 0,否则返回错误代码 void pthread_exit(void *retval) 调用上面函数终止线程 返回一个指向某个对象的指针 注意:不能用它来返回一个指向局部变量的指针,因为线程调用该函数后,这个局部变量就不存在了 pthread_join int pthread_join( pthread_t th, void *thread_return) 等待线程结束,收集线程信息 参数 1.指定了将要等待结束的线程 参数 2. 是一个指针,指向了

10、一个指针,后者指向线程的返回值 例子 #include #include #include #include void *thread_function(void *arg); char message = “Hello world“; int main() int res; pthread_t a_thread; void *thread_result; res = pthread_create( if(res !=0)perror(“Thread creation failed“); exit(EXIT_FAILURE); printf(“Waiting for thread to fin

11、ishn“); res = pthread_join(a_thread, if(res !=0)perror(“Thread join failed“); exit(EXIT_FAILURE); printf(“Thread joined, it returned %sn“,(char*)thread_result); printf(“Message is now %sn“,message); exit(EXIT_SUCCESS); void *thread_function(void *arg) printf(“thread_function is running. Argument was

12、 %s n“,(char *)arg); sleep(3); strcpy(message,“Bye!“); pthread_exit(“Thank you for the CPU time“); 运行结果 Waiting for thread to finish. thread_function is running. Argument was Hello world Thread joined, it returned Thank you for the CPU time Message is now Bye! 编译须知: gcc -lpthread -o file file.c 随堂作业

13、 3.4 3.6 4.7 4.11 3.6 Fibonacci序列是一组: 0,1,1,2,3,5,8, fib0=0; fib1=1; fibn=fibn-1+fibn-2; 使用系统调用 fork()编写一个 C程序,它在其子程序中生成 Fibonacci序列,序列号码将会在命令行中提供。例如,如果提供的是 5, Fibonacci序列中的前 5个数将由子进程输出。由于父进程和子进程都有他们自己的数据副本,对子进程而言,输出序列式必要的。退出程序前,父进程调用 wait()调用来等待子进程结束。执行必要的错误检查以保证不会接受命令行传递来的负数号码。 4.11 Fibonacci序列是一组: 0,1,1,2,3,5,8, fib0=0; fib1=1; fibn=fibn-1+fibn-2; 使用 phtread多线程编程程序来生成 Fibonacci序列。程序应该这样工作:用户运行程序时,在命令行输入要产生 Fibonaci序列数,然后程序创建一个新的线程来产生 Fibonacci数,把这个序列放到线程共享的数据中(数组可能是一种最方便的数据结构)。当线程执行完成后,父线程将输出子线程产生的序列。由于在子线程结束前,父线程不能开始输出Fibonacci序列,因此,父线程需要等子线程结束

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 企业管理 > 管理学资料

本站链接:文库   一言   我酷   合作


客服QQ:2549714901微博号:道客多多官方知乎号:道客多多

经营许可证编号: 粤ICP备2021046453号世界地图

道客多多©版权所有2020-2025营业执照举报