1.守护线程的创建
定义:周期性的执行某项任务或等待某个事件发生的进程,不依赖shell终端,生存周期较长。(从开机开始到关机结束)。
守护进程的创建步骤:
- 创建一个子进程,让父进程退出。
fork() - 在子进程中,创建新的会话期
脱离当前会话期。
setsid();创建新会话期的函数。 - 改变子进程的工作目录
chdir(“/”);改为根目录,因为根目录永远不会被删除。 - 取消文件权限掩码
将文件的某一个权限掩掉,取消其他用户中的写操作
恢复文件原来具有的权限。
umask(0);与操作
文件111 110 111 777–>775
000 000 010 - 关闭所有文件描述符
系统最多一下打开1024个,stdin、stdout、stdout默认打开,剩下1021个。
getdtablesize();//获取该系统可以一下最多打开多少个文件
守护进程创建案例代码:
#include<stdio.h>
#include<unistd.h>
#include<stdlib.h>
#include<sys/types.h>
#include<sys/stat.h>
int main()
{
int i;
//fork创建子进程
pid_t pid=-1;
pid=fork();
if(-1==pid)
{
return -1;
}
if(pid>0)
{
exit(0);
}
printf("1:fork OK!\r\n");
//2set new section
setsid();
printf("2:create new section OK!pid=%d\r\n",getpid());
//3 chdir /
chdir("/");
//4.取消文件掩码
umask(0);
//5.close all file
int num=getdtablesize();
//获取该系统可以最多一下打开多少个文件
for(i=0;i<num;i++)
{
close(i);
}
sleep(20);
return 0;
}
关于目录操作的函数:
opendir();chdir();readdir();
2.线程相关
定义:线程是轻量级的进程,用task_struct表示,他没有自己独立的内存空间,它与其他线程共享创建它的进程的地址空间。
3.线程创建
可以使用第三方线程库提供的API(接口)
pthread_create测试案例:
#include<stdio.h>
#include<pthread.h>
void *ThreadFunc(void *arg)
{
printf("test by all@1201---------------\r\n");
}
int main()
{
printf("hello world\r\n");
pthread_t tID=-1;
if(0!=pthread_create(&tID,NULL,ThreadFunc,NULL))
{
printf("create pthread error\r\n");
return -1;
}
// char *pStr=NULL;
pthread_join(tID,NULL);
printf("hello 22101------------\r\n");
return 0;
}
退出当前子线程
发送终止信号给thread线程,如果成功则返回0,否则为非0值。发送成功并不意味着thread会终止。有时会终止线程的运行,有时不会。看系统的运行定
#include<stdio.h>
#include<pthread.h>
void *ThreadFunc(void *arg)
{
printf("test by all@1201---------------\r\n");
}
int main()
{
printf("hello world\r\n");
pthread_t tID=-1;
if(0!=pthread_create(&tID,NULL,ThreadFunc,NULL))
{
printf("create pthread error\r\n");
return -1;
}
//参数:线程号
//成功返回0,失败返回非零数
if(0!=pthread_cancel(tID))
{
printf("线程取消失败\r\n");
}
printf("hello 22101------------\r\n");
return 0;
}
unubtu的组成=Linux内核+各种工具+桌面+各种库+已经写好的各种应用程序
4.多线程的通信 同步 互斥
在一个进程中可以创建多个线程,那么多个线程间会存在数据通信问题,会存在两个线程相互配合完成一件事情(线程同步),会存在两个线程对公共资源的竞态访问问题(互斥问题)。
案例同时创建多个线程:
#include<stdio.h>
#include<pthread.h>
void *ThreadFunc1(void *arg)
{
printf("test by fun1---------------\r\n");
}
void *ThreadFunc2(void *arg)
{
printf("test by fun2----------------\r\n");
}
int main()
{
printf("hello world\r\n");
pthread_t tID1=-1;
pthread_t tID2=-1;
if(0!=pthread_create(&tID1,NULL,ThreadFunc1,NULL))
{
printf("create pthread error\r\n");
return -1;
}
if(0!=pthread_create(&tID2,NULL,ThreadFunc2,NULL))
{
printf("create pthread2 error!\r\n");
return -1;
}
// char *pStr=NULL;
pthread_join(tID1,NULL);
pthread_join(tID2,NULL);
printf("hello 22101------------\r\n");
return 0;
}
查看系统可以支持的最大线程数和最大进程数指令。
①系统支持的最大线程数
②系统支持的最大进程数
4.1多线程的数据通信
使用全局变量实现
4.2多线程的同步
用无名信号量 sem_t sem;
同步:两个线程相互配合按照一定的顺序完成一件事情。
pthread1–>hello 1s sem_t sema;–>P/V操作函数控制sema和semb
pthread2–>world 1s sem_t semb;
P操作:sem_wait(&sema);
含义:sem_wait会检测信号量sema的值是否大于0,若大于0,将sema减1,同时函数返回。若等于0,则阻塞当前线程
V操作:sem_post(&sema);----->非阻塞函数
含义:sem_post只会给检测的信号量sema+1;
实现打印:hello world hello world…
案例:
#include<stdio.h>
#include<pthread.h>
#include<semaphore.h>
sem_t sema;
sem_t semb;
void *ThreadFunc1(void *arg)
{
int i=10;
while(i--)
{
sem_wait(&sema);
printf("hello-----\r\n");
sleep(1);
sem_post(&semb);//将semb置1
}
}
void *ThreadFunc2(void *arg)
{
int i=10;
while(i--)
{
sem_wait(&semb);
printf("world-----------------\r\n");
sleep(1);
sem_post(&sema);//'将sema置为1
}
}
int main()
{
printf("hello world\r\n");
pthread_t tID1=-1;
pthread_t tID2=-1;
if(-1==sem_init(&sema,0,1)||-1==sem_init(&semb,0,0))
{
return -1;
}
if(0!=pthread_create(&tID1,NULL,ThreadFunc1,NULL))
{
printf("create pthread error\r\n");
return -1;
}
if(0!=pthread_create(&tID2,NULL,ThreadFunc2,NULL))
{
printf("create pthread2 error!\r\n");
return -1;
}
// char *pStr=NULL;
pthread_join(tID1,NULL);
pthread_join(tID2,NULL);
printf("hello 22101------------\r\n");
return 0;
}
4.3多线程的互斥
互斥:多个线程可能会使用同一段公共资源,若是同时访问这一段公共资源就会造成多个线程对公共资源竞争,从而造成访问结果混乱。
如何解决?可以使用互斥锁
1.多个线程是否受用同一个线程执行函数
2.两个线程给线程执行函数传入不同的参数,最后结果是否发生混乱。
3.使用互斥锁解决两线程的互斥访问公共资源
pthread_mutex_t mutex;//定义了一个全局的线程互斥锁
pthread_mutex_init(&mutex,NULL(互斥锁的默认属性));
pthread_mutex_unlock(&mutex);