进程、线程操作实例

管道:

   无名管道(仅适用于亲缘进程)

   1、创建管道 利用 pipe 函数, 在创建前定义一个整型数组,

   例:int fd[2];

       pipe(fd); // fd[0]读描述符,fd[1]写描述符

    2、写

    例:write(fd[1],"hello",5);

    3、读

    例:read(fd[0], buf, sizeof(buf));

   有名管道

   1、创建管道 利用mkfifo 函数

   例:mkfifo("/home/china/fifo1", 0644);

    2、打开管道文件  返回文件标识符

   例:int fd = open("/home/china/fifo1", O_RDWR);

    3、写

    例:write(fd, buf, strlen(buf));

    4、读

    例:read(fd,buf,sizeof(buf));  //等待 管道有数据可读

信号量:

   无名信号量:

  1. 在所有线程都能访问到的地方定义一个 sem_t 类型的变量

    例:sem_t sem;

       2、对无名信号量进行初始化,利用sem_init 函数

    函数原型:int sem_init(sem_t *sem, int pshared, unsigned int value);

  1. 对信号量进行P操作 利用函数 sem_wait 、sem_trywait   

   函数原型:int sem_wait(sem_t *sem);

               int sem_trywait(sem_t *sem);

    int sem_timedwait(sem_t *sem, const struct timespec *abs_timeout);

  1. V操作 利用sem_post函数

      函数原型:int sem_post(sem_t *sem);

  1. 不在需要时,需要销毁 利用 sem_destroy 函数

   函数原型:int sem_destroy(sem_t *sem);

    有名信号量

    1、创建或打开一个有名信号量 利用 sem_open 函数

    例:sem_t * fd_sem = sem_open("/my_sem_name", O_CREAT  , 0644 , 0 );

    2、P 操作  利用 sem_wait 函数

   例:sem_wait(fd_sem);

    3、V操作

    例:sem_post(fd_sem);

    4、关闭信号量

    例:sem_close(fd_sem);

    5、删除信号量

   例:sem_unlock(fd_sem);

消息队列:

   1、创建一个唯一键值 key ,利用 ftok 函数

    例:key_t key = ftok("/home/china",'S');

    2、创建或打开消息队列 , 利用 msgget 函数, 创建成功返回队列ID(标识符)

   例:int msqid = msgget(key, IPC_CREAT|0644);

   3、定义一个消息队列的结构体并定义一个结构体变量  用于发送和接收消息时使用

    例:struct msgbuf {

         long mtype; /* message type, must be > 0 */

       char mtext[100]; /* message data */};

       struct msgbuf msg1;

       msg1.mtype = 1; //消息的类型

    4、向消息队列发送消息  利用函数 msgsnd 

    例:msgsnd(msqid, &msg1, strlen(msg1.mtext), 0);

   

    5、接收消息  返回实际接收的字节数

    例:int n = msgrcv(msqid, &msg1, strlen(msg1.mtext), 1, 0);

共享内存:

    1、创建一个唯一键值 key ,利用 ftok 函数

    例:key_t key = ftok("/home/china",'S');

    2、创建一个共享内存 , 利用 shmget 函数,创建成功返回共享内存标识符

    例:int shmid = shmget(key, 100, IPC_CREAT|0644);

    注意:为什么已经有一个key来标识共享内存,还想要共享内存标识符来标识呢?

    因为key是内核级别的,供内核标识,而共享内存标识符是用户级别,为了供用户标识

    3、共享内存关联进程,利用 shmat 函数,创建成功返回映射到进程地址共享空间的开始地址

    例:char *p = shmat(shmid, NULL, 0);

   4、删除共享内存与进程的关联  利用shmdt 函数

    例:shmdt(p);

    注意:IPC(进程间通信)资源生命周期不随进程,而是随内核,在进程结束后,共享内存还在,在第二次执行时会报错,所以,shmget 创建的共享内存要在使用结束后释放掉,不然内存会泄露。

    5、释放共享内存  利用 shmctl 函数 (一般为服务端释放)

    例:int sh = shmctl(shmid, IPC_RMID, NULL);

线程:

  1. 先定义线程id  

    例:pthread_t tid1;

  1. 创建线程 利用 pthread_create 函数,创建线程同时调用线程函数

    例:pthread_create(&tid1, NULL,pthread1, &tid1);

   

  1. 线程退出 利用 pthread_exit 或其他线程调用 pthread_cancel

    例:void pthread_exit(void *retval);

        int pthread_cancel(pthread_t thread);

  1. 等待回收线程id 利用函数 pthread_join

    例:pthread_join(tid1, NULL);

线程之间的同步 —信号量、线程互斥锁

线程互斥锁:

  1. 声明并初始化线程互斥锁

    例:pthread_mutex_t  mutex1 = PTHREAD_MUTEX_INITIALIZER;

或:int pthread_mutex_init(pthread_mutex_t *restrict mutex,const pthread_mutexattr_t *restrict attr);

    2、p/v操作

    例:pthread_mutex_lock(&mutex1);

       pthread_mutex_unlock(&mutex1);

    3、销毁互斥锁

    例:pthread_mutex_destroy(&mutex1);

条件变量:

    1、声明并初始化一个条件变量

    例:pthread_cond_t hasApple = PTHREAD_COND_INITIALIZER;

或:int pthread_cond_init(pthread_cond_t *restrict cond, const pthread_condattr_t *restrict attr);

    2、等待一个条件变量 可以理解为让线程睡眠

    例:pthread_cond_wait(&hasEmpty, &lock);

    3、唤醒线程

    例:pthread_cond_signal(&hasEmpty);

线程池

线程池就是创建一个线程的集合,再创建一个任务的队列,任务列中任务的执行依靠线程池的的线程,当任务执行完后归还线程回去等待下一任务使用,可避免线程频繁的创建和销毁

  1. 创建任务队列
  2. 创建线程池
  3. 初始化线程池
  4. 给任务队列中添加任务
  5. 调用任务执行
  6. 销毁线程池

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值