守护进程与线程互斥

来源:互联网 发布:小辣椒淘宝店 编辑:程序博客网 时间:2024/05/21 19:21

一、守护进程的创建

守护进程一般运行在后台,随系统启动一起启动,系统关闭才结束。那该如何创建守护进程呢?

有一个智力题:怎样把一头大象放进冰箱里呢?1.打开冰箱的门;2.把大象放进去;3.关闭冰箱的门。创建守护进程也一样,虽然复杂,但按照一定的步骤即可轻松创建。

其步骤是:

1.     创建子进程,结束父进程;

2.创建新的会话期。即调用setsid()函数。因为父进程结束后,子进程就成了孤儿进程,他依然属于原来父进程的会话组。

调用setsid3个作用:

a)       让进程摆脱原会话的控制;

b)      让进程摆脱原进程组的控制;

c)       让进程摆脱原控制终端的控制;

3.切换目录至根目录。由于守护进程一直运行,如果不切换目录,当该目录需要卸载的时候就无法卸载。当然,在系统运行时根目录是不可能被卸载的。

4.调用系统函数umask改变文件权限掩码。守护进程的权限应该是很高的,不然有些操作将无法执行,将文件权限掩码设为0时,就不会屏蔽用户的操作。

5.关闭不需要的文件。守护进程运行在后台,不需要输入与输出,但在进程创建的时候,操作系统为每个进程打开3个文件流,stdinstdoutstderr。因此这些流都需要关闭。如果不清楚打开了多少的文件流,可以使用getdtablesize()返回打开文件流的范围,即可关闭所以打开的文件流。

接下来我们创建一个守护进程,使其每3秒向/tmp/timeupdate.txt中写入当前的时间。

#include <sys/types.h>#include <sys/wait.h>#include <unistd.h>#include <stdlib.h>#include <time.h>#include <stdio.h>#include <string.h>#include <sys/stat.h>#include <fcntl.h>int main(){pid_t pid;int i,n;time_t t;FILE *fp;char buf[40];if((pid=fork())<0)                      //第一步,创建子进程,结束父进程{perror("fork");return -1;}else if(pid>0){exit(0);}setsid();                              //第二步,创建新的会话期chdir("/");                            //第三步,更改路径umask(0);                              //第四步,更改文件权限掩码n = getdtablesize();                   //第五步,关闭打开的文件流for(i=0 ; i<n ; i++)close(i);if((fp=fopen("/tmp/timeupdate.txt","a+")) == NULL){perror("open");return -1;}while(1)                               //守护进程应该一直运行{time(&t);sprintf(buf,"%s",ctime(&t));n = strlen(buf);fwrite(buf,n,1,fp);fflush(fp);sleep(3);}fclose(fp);return 0;}


 

二、经典互斥问题,生产者与消费者问题。

#include<stdio.h>#include<pthread.h>#include<semaphore.h>#include<string.h>#include<stdlib.h>sem_t s1,s2;char buf[100];void *consumer(void *p){while(1){sem_wait(&s2);printf("Consumer : ");puts((char *)p);printf("\n");sem_post(&s1);}return p;}int main(){pthread_t pid;if(sem_init(&s1,0,1)<0){perror("Init sem_t s1");exit(-1);}if(sem_init(&s2,0,0)<0){perror("Init sem_t s2");exit(-1);}if(pthread_create(&pid,NULL,consumer,buf)<0){perror("Create pthread");exit(-1);}printf("Input 'quit' to exit\n");do{sem_wait(&s1);printf("Produce ......\n");fgets(buf,sizeof(buf),stdin);buf[strlen(buf)-1] = 0;             //过滤输入的'\n'sem_post(&s2);}while(strcmp(buf,"quit")!=0);return 0;}

0 0
原创粉丝点击