Linux 学习笔记

第一章 多进程与多线程

1 Linux 进程

1.1 进程基础

1.1.1 创建进程 fork()
-	返回值: 
a)	成功:给父进程返回:子进程ID,给子进程返回:0
b)	失败:-1
		//创建子进程
		fork函数调用后发生的事情:
		1)	分配子进程的虚拟空间
		2)	将父进程的所有数据段中的内容拷贝到子进程对应的段中
		3)	父子进程共享代码段
		4)	fork函数分别给父子进程返回一个值:给父进程返回:子进程ID,给子进程返回:0
		5)	fork返回后,父子进程同时从fork()调用的下一条语句开始执行
  • 例如
	int main(void)
	{
		pid_t pid;
		pid = fork();

		if (pid < 0) {
			perror("fork");
			exit(1);
		}
		
		else if (pid > 0) /* 父进程执行的代码 */
		{
			printf("我是爸爸:\n");
			while (1)
			{
				printf("每天要赚钱\n");
				sleep(1);
			}
		}
		
		else /* 子进程执行的代码 */
		{
			printf("我是儿子:\n");
			while (1)
			{
				printf("每天要花钱\n");
				sleep(1);
			}
		}
		return 0;
	}
1.1.2 exec 函数族
	//加载另一个程序到某个进程空间中执行
	int execl(const char *path, const char *arg, ...);
	int execlp(const char *file, const char *arg, ...);
	int execle(const char *path, const char *arg, ..., char * const envp[]);
	
	int execv(const char *path, char *const argv[]);
	int execvp(const char *file, char *const argv[]);
	int execvpe(const char *file, char *const argv[],char *const envp[]);
	
	/* 注意: 
	1)通过程序名称寻找程序时,会去/bin 或 /usr/bin中找,如果程序在其他位置,则只能通过路径找
	2)传递程序执行的格式时,最后一个参数必须是NULL,表示参数结束
	3)当把一个程序加载到进程空间中执行时,进程中所有段中原来的数据和代码全部被该程序替换(覆盖)
	*/
1.1.3 wait和waitpid
  • ​ pid_t wait(int *status);

    给任意一个子进程收尸,如果子进程没有结束,会使父进程阻塞,直到子进程结束为止。
    参数	------	子进程结束状态
    返回值	------	成功:被收尸的子进程的pid,失败:-1
    
  • id_t waitpid(pid_t pid, int *status, int options);

    //给指定的子进程收尸
    //参数1 ----- pid :
    			pid>0//给子进程ID号为pid的子进程收尸,如果指定的子进程没有结束,则一直阻塞。
    			pid=-1//等待任何一个子进程退出,此时和wait作用一样。 
    			pid=0//等待其组ID等于调用进程的组ID的任一子进程。 
    			pid<-1//等待其组ID等于pid的绝对值的任一子进程
    				
    //参数2 ----子进程结束状态
    //参数3 ---- options
    			WNOHANG:若由pid指定的子进程并不立即可用,则waitpid不阻塞,此时返回值为0 
    			WUNTRACED:若某实现支持作业控制,则由pid指定的任一子进程状态已暂停,且其状态自暂停以来还未报告过,则返回其状态。 
    				0:同wait,阻塞父进程,等待子进程退出。
    

2 守护进程

2.1 创建步骤

  • 1 创建子进程

    pid = fork()

  • 2 创建新会话

    setsid()

  • 3 忽略父进程结束产生的信号:SIGHUP影响

    signal(SIGHUP,SIG_IGN);

  • 4 创建子进程

    pid = fork()

  • 5 关闭所有文件描述符

int max_fd = sysconf(_SC_OPEN_MAX);
for(int i = 0; i < max_fd;i++)
    close(i);
  • 6 消除umask影响

    umask(0);

  • 7 修改守护进程的工作目录为系统根目录

    chdir("/");

  • 8 重定向标准输入,标准输出,标准错误输出

    open("/dev/null",O_RDWR);
    dup(0);
    dup(0);
    
    
    
    

3 多线程

3.1 创建线程

#include <pthread.h>

int pthread_create(pthread_t *thread, const pthread_attr_t *attr,
                   void *(*start_routine) (void *), void *arg);

Compile and link with -pthread. 

【注1】:参数3需要定义函数 void *my_fun(void * mydata), 传入my_fun

【注2】:编译时 + -lpthread

3.2 线程同步操作

  • 初始化
#include <semaphore.h>

int sem_init(sem_t *sem, int pshared, unsigned int value);

  • 等待/释放

    #include <pthread.h>
    int sem_wait(sem_t *sem);
    int sem_post(sem_ *sem);
    

3.3 互斥访问

static pthread_mutex_t g_tMutex = PTHREAD_MUTEX_INITIALIZER;
pthread_mutex_lock(&g_tMutex);
pthread_mutex_unlock(&g_tMutex);

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值