Linux进程3

本文深入探讨了Linux进程中的多线程同步互斥机制,包括线程互斥锁、无名信号量和条件变量的使用。同时,详细介绍了进程间通信的各种方式,如无名管道、有名管道和信号的原理、API及实际应用案例,为理解和实现Linux进程间的高效通信提供了全面的知识框架。
摘要由CSDN通过智能技术生成

目录

1.1多线程拷贝文件

2.多线程同步互斥机制

2.1什么是同步?什么是互斥?

2.2线程互斥锁

2.2.1线程互斥锁API

2.2.2线程互斥锁的实例

2.3无名信号量

2.3.1无名信号量的API

2.3.2线程同步的实例

2.4条件变量

2.4.1条件变量的API

2.4.2条件变量的实例1(一个线程)

2.4.2条件变量的实例2(多个线程)

2.4.3什么时候使用条件变量

3.进程间通信

3.1进程间通信的种类

3.2无名管道

3.2.1无名管道实现进程间通信的原理

3.2.2无名管道的API

3.2.3使用无名管道实现进程间通信实例

3.2.4无名管道读写的特点

3.3有名管道

3.3.1有名管道的原理

3.3.2有名管道的API

3.3.3有名管道实现进程间通信

3.3.4有名管道读写的特点

3.4信号

3.4.1什么是信号?

3.4.2如何查看信号

3.4.3常用的信号

3.4.4通过命令发信号

3.4.5信号处理函数API

3.4.6信号处理函数使用实例


1.1多线程拷贝文件

#include <head.h>
typedef struct {
    const char* src;
    const char* dest;
    int start;
    int len;
} file_t;
int GetFileLen(const char* filename)
{
    int fd, len;
    if ((fd = open(filename, O_RDONLY)) == -1)
        PRINT_ERR("open src error");

    len = lseek(fd, 0, SEEK_END);

    close(fd);
    return len;
}
int InitFile(const char* filename)
{
    int fd;
    if ((fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC, 0666)) == -1)
        PRINT_ERR("open src error");

    close(fd);

    return 0;
}
int copy_file(const char* src, const char* dest, int start, int len)
{
    int sfd, dfd, ret, count = 0;
    char buf[20] = { 0 };
    // 1.打开两个文件
    if ((sfd = open(src, O_RDONLY)) == -1)
        PRINT_ERR("open srcfile error");
    if ((dfd = open(dest, O_RDWR)) == -1)
        PRINT_ERR("open destfile error");

    // 2.定位光标
    lseek(sfd, start, SEEK_SET);
    lseek(dfd, start, SEEK_SET);

    // 3.循环拷贝
    while (1) {
        ret = read(sfd, buf, sizeof(buf));
        count += ret;
        if (count >= len) {
            write(dfd, buf, ret - (count - len));
            break;
        }
        write(dfd, buf, ret);
    }

    close(sfd);
    close(dfd);

    return 0;
}
void* Task(void* arg)
{
    file_t *f = (file_t *)arg;

    copy_file(f->src, f->dest, f->start, f->len);

    pthread_exit(NULL);
}

int main(int argc, const char* argv[])
{
    pthread_t tid1, tid2;
    int len;
    // 1.通过命令行输入源文件和目标文件
    if (argc != 3) {
        fprintf(stderr, "input error,try again\n");
        fprintf(stderr, "usage:./a.out srcfile destfile\n");
        return -1;
    }

    // 2.获取源文件的大小
    if ((len = GetFileLen(argv[1])) == -1)
        return len;

    // 3.初始化目标文件
    InitFile(argv[2]);

    //4.初始化结构体
    file_t f[] = {
        [0] = {
            .src = argv[1],
            .dest = argv[2],
            .start = 0,
            .len = len / 2,
        },
        [1] = {
            .src = argv[1],
            .dest = argv[2],
            .start = len / 2,
            .len = len - (len / 2),
        },
    };

    if (errno = pthread_create(&tid1, NULL, Task, (void *)&f[0]))
        PRINT_ERR("pthread 1 create error");

    if (errno = pthread_create(&tid2, NULL, Task, (void *)&f[1]))
        PRINT_ERR("pthread 2 create error");

    pthread_join(tid1, NULL);
    pthread_join(tid2, NULL);
    return 0;
}

2.多线程同步互斥机制

2.1什么是同步?什么是互斥?

当多个线程同时访问临界资源的时候,竞态就产生了。解决竞态的方式可以使用线程的同步机制,

也可以使用线程的互斥机制。

互斥:是多个线程同时在争抢资源的过程,具体那个线程能够争抢到资源不确定。

同步:对对个线程的执行提前编排好顺序,在线程执行的时候按照顺序执行即可。

竞态的代码

#include <head.h>
int money = 10000;
void* Task1(void* arg)
{
    while (1) {
        money -= 50;
        if (money >= 0) {
            printf("张三取了50块钱成功,剩余=%d\n", money);
        } else {
            printf("余额小于50块钱\n");
            pthread_exit(NULL);
        }
        sleep(1);
    }
}

void* Task2(void* arg)
{
    while (1) {
        money -= 100;
        if (money >= 0) {
            printf("李四取了100块钱成功,剩余=%d\n", money);
        } else {
            printf("余额小于100块钱\n");
            pthread_exit(NULL);
        }
        sleep(1);
    }
}
int main(int argc, const char* argv[])
{
    pthread_t tid1, tid2; //线程号
    //创建线程1
    if (errno = pthread_create(&tid1, NULL, Task1, NULL))
        PRINT_ERR("pthread create error");

    //创建线程2
    if (errno = pthread_create(&tid2, NULL, Task2, NULL))
        PRINT_ERR("pthread create error");

    pthread_join(tid1, NULL);
    pthread_join(tid2, NULL);

    return 0;
}

2.2线程互斥锁

线程互斥锁:线程首先要获取互斥锁,当获取互斥锁之后才能够操作临界资源,此时其他的线程获取互斥锁的时候不成功,让线程处于休眠状态。当前前面的线程解锁之后,后面的线程才有可能获取锁成功,从休眠状态重新变为运行的状态,执行临界资源的代码。以此类推...

2.2.1线程互斥锁API

#include <pthread.h>
1.定义互斥锁
pthread_mutex_t lock;   
    
2.初始化互斥锁
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
//互斥锁的静态初始化
int pthread_mutex_init(pthread_mutex_t * mutex, const pthread_mutexattr_t * attr);
功能:互斥锁的动态初始化
参数:
   @mutex:锁的变量的地址
   @attr:NULL,缺省属性
功能:成功返回0,失败返回非0
       
3.上锁
int pthread_mutex_lock(pthread_mutex_t *mutex);
功能:上锁,如果获取不到锁阻塞等待
参数:
   @mutex:变量的地址
返回值:成功0,失败非0
   
4.解锁
int pthread_mutex_unlock(pthread_mutex_t *mutex);
功能:解锁
参数:
   @mutex:变量的地址
返回值:成功0,失败非0
    
5.销毁锁
int pthread_mutex_destroy(pthread_mutex_t *mutex);
功能:销毁锁
参数:
   @mutex:变量的地址
返回值:成功0,失败非0 

2.2.2线程互斥锁的实例

#include <head.h>
// 1.定义互斥锁
pthread_mutex_t lock;

int money = 10000;
void* Task1(void* arg)
{
    // 3.使用锁
    while (1) {
        pthread_mutex_lock(&lock);
        money -= 50;
        if (money >= 0) {
            printf("张三取了50块钱成功,剩余=%d\n", money);
        } else {
            printf("余额小于50块钱\n");
            pthread_mutex_unlock(&lock);
            pthread_exit(NULL);
        }
        usleep(10000);
        pthread_mutex_unlock(&lock);
    }
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值