基于linux的C语言

目录

一,线程的相关知识

        1,线程的概念

        2,多线程的概念

二,线程的操作

        1,线程的创建

        2,线程的关闭

        3,线程的等待

        4,线程的取消

 三,线程间的同步互斥

        1,基本概念

        2,(同步)信号量允许的三个操作

                2.1,初始化

                2.2,p操作

                2.3,v操作

        3,互斥

                3.1,互斥锁的初始化

                3.2,互斥锁的加锁

                3.3,互斥锁的解锁

四,进程间的通信

        1,基本概念

                1.1,管道

                1.2,信号

                1.3,共享内存

                1.4,消息队列

                1.5,信号灯

        2,管道的操作

                2.1,有名管道的创建

                2.2,无名管道的创建

        3,信号的操作

                 3.1,信号的发送

                3.2,信号的捕获

                3.3,定时发送信号alarm

                3.4,阻塞等待信号的接收pause

        4,共享内存的操作

                4.1,创建共享内存

                4.2,映射共享内存

                4.3,解除映射共享内存

                4.4,关闭共享内存

        5,消息队列的操作

                5.1,创建消息队列

                5.2,添加 / 读取 消息队列

                5.3,删除消息队列

        6,信号灯的操作

                6.1,信号量的创建

                6.2,信号量的操作

                6.3,信号量的控制


一,线程的相关知识

        1,线程的概念

       每个进程都是独⽴的私有的空间,是⼀个独⽴的任务,虽然可能多个进程相 互之间需要协同⼯作,但需要系统⾃⼰的对进程间进行切换,因此在进程的上下⽂切换时,系统开销⽐较⼤ 为了提高系统的性能,在操作系统中引⼊了轻量级的进程,也叫做线程。

        线程包含在进程内,每条线程都是进程中单一顺序的控制流,一个进程可以并发多条线程,且每个线程执行不同的任务。线程之间的资源是共享的。

        2,多线程的概念

       在一个程序中,存在许多费时的操作,如果使用单线程,程序只能顺序执行,只有等待当前操作完成后才能执行下一操作,造成资源浪费,影响执行效率,使用多线程就可以将耗时的操作任务放在后台工作,且同时执行其他操作,从而提高工作效率。 

        多线程就是指一个进程中同时有多个线程正在执行。

二,线程的操作

        1,线程的创建

#include <pthread.h>

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

/*
返回值
    成功:返回0;
    失败:返回错误码
*/


/*
参数1:
    pthread_t *thread:指针,地址,(存储线程id)创建线程后会把线程id存储到这个地址中。
参数2:
    const pthread_attr_t *attr:要执⾏的线程的属性,传递的是属性变量值的地址,通常 写 NULL 表⽰使⽤默认属性创建线程。
参数3:
    void *(*start_routine) (void *):函数指针,函数地址,线程执⾏的起始函数,线程从哪个函数开始执⾏
参数4:
    void *arg:提供给参数3这个函数的参数。
*/

        2,线程的关闭

        结束当前线程,同时把线程结束状态,返回给创建当前线程的进程或线程 中。

 #include <pthread.h>

void pthread_exit(void *retval);

/*
参数:
    void *retval:指针,地址,作为线程的结束状态,返回给创建的线程中。
*/

        3,线程的等待

        等待线程结束,并接收线程结束的状态。

#include <pthread.h>

 int pthread_join(pthread_t thread, void **retval);

/*
返回值:
    成功:0;
    失败:错误码;
*/

/*
参数1:
    pthread_t thread:要等待结束的线程id
参数2:
    void **retval:⼆级指针,⼀级指针的地址,把线程结束状态(⼀级指针),存储到这个地址中。
*/

        4,线程的取消

        取消指定线程的执行。

#include <pthread.h>

int pthread_cancel(pthread_t thread);
/*
参数:
    pthread_t thread:线程的编号。
*/

 三,线程间的同步互斥

        1,基本概念

        互斥:在同一时刻,有且只有一个任务访问一个资源

        同步:在互斥的基础上,访问有着一定的先后顺序,由信号量完成。

        信号量:一个非负整数,代表着一类资源。被用来控制对公共资源的访问。编程时可根据操作信号量值的结果判断是否对公共资源具有访问的权限,当信号量值大于0时,则可以访问,否则将阻塞。PV操作即对信号量的操作,-次P操作使信号量减1, - -次V操作使信号量加1。

        注:当信号量用于同步时,需要多个信号量同时工作,而用于互斥时只需一个信号量即可。

        P操作:(申请资源)只有当信号量大于0时,任务才能进行,否则,任务阻塞。

        v操作:(释放资源)

        2,(同步)信号量允许的三个操作

                2.1,初始化

#include <semaphore.h>

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

/*
参数1:
    sem_t *sem:地址,信号量的地址,把初始化的值存⼊这个变量地址中
参数2:
    int pshared:信号量使⽤的范围 0:表⽰在线程间使⽤;⾮0:表⽰在进程间使⽤。
参数3:
    unsigned int value:信号量初始化的值
*/

/*
返回值:
    成功:返回0
    失败:返回-1
*/

                2.2,p操作

        资源信号量 减减,但sem==0就不能继续 减减  ⽽是阻塞等待

#include <semaphore.h>

int sem_wait(sem_t *sem);

                2.3,v操作

#include <semaphore.h>

int sem_post(sem_t *sem);

        举例:

#include<stdio.h>
#include<pthread.h>
#include<stdlib.h>
#include<unistd.h>
#include<semaphore.h>

int num;
sem_t rw;
void * thread_write(void * arg)    //写
{
	int i = *(int *)arg;
	while(i--)
	{
		num = i;
		sem_post(&rw);            //p操作
		sleep(2);
	}
	return NULL;
}

void *	thread_read(void * arg)    //读
{
	while(1)
	{
		sem_wait(&rw);            //v操作
		printf("num==%d\n",num);
	}
	return NULL;
}

int main()
{
	pthread_t tid1,tid2;
	sem_init(&rw,0,5);            //初始化
	int n=10;
	pthread_create(&tid1,NULL,thread_write,&n);
	pthread_create(&tid2,NULL,thread_read,NULL);
	exit(0);
}

        3,互斥

        互斥锁:就是每个线程在⾃⼰线程中访问资源,当能够获取到锁(加锁)时就访 问,访问完就释放锁(解锁)。当线程⽆法获得锁时,就阻塞等待直到获得锁为 ⽌。

        注:加锁后一定要记得解锁。

                3.1,互斥锁的初始化

         初始化互斥锁,设置互斥锁变量

#include <pthread.h>

int pthread_mutex_init(pthread_mutex_t * mutex,constpthread_mutexattr_t * attr);

/*
参数1:
    pthread_mutex_t * mutex:互斥锁变量地址,要初始化的互斥锁变量
参数2:
    pthread_mutexattr_t * attr:互斥锁的属性,NULL表⽰默认属性
返回值:
    成功:返回0
    失败:返回-1
*/</
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,关于您所提到的问题,我能够给您一些基本的思路和实现方法。管道通信是Linux系统中一种非常常见的进程间通信方式,可以实现不同进程之间数据的传输和共享。下面是一份基于Linux C语言的管道通信例程,您可以参考一下: 1. 父进程创建一个管道,通过fork()函数创建一个子进程来读取管道中的数据。 ``` #include <stdio.h> #include <stdlib.h> #include <unistd.h> int main(){ int fd[2]; pid_t pid; char buffer[20]; //创建管道 if(pipe(fd)<0){ printf("Create pipe error!\n"); exit(1); } //创建子进程 pid = fork(); if(pid < 0){ printf("Create process error!\n"); exit(1); }else if(pid == 0){ //子进程读取管道中的数据 close(fd[1]); int n = read(fd[0], buffer, sizeof(buffer)); printf("Child process received: %s\n", buffer); close(fd[0]); }else{ //父进程向管道中写入数据 close(fd[0]); char* data = "Hello, child process!"; write(fd[1], data, sizeof(data)); printf("Parent process sent: %s\n", data); close(fd[1]); } return 0; } ``` 2. 父进程向管道中写入数据,子进程进行读取并输出。 以上面的代码为例,首先父进程通过pipe()函数创建了一个管道fd,接着通过fork()函数创建了一个子进程,并通过pid变量来判断当前进程是否为父进程或子进程。在父进程中,我们先关闭了管道的读端,然后通过write()函数向管道中写入了数据"data",并输出了发送成功的信息。在子进程中,我们先关闭了管道的写端,然后通过read()函数从管道中读取数据到buffer缓冲区中,并输出读取的结果。 这就是一个简单的基于Linux C语言的管道通信例程实现方法。当然,具体实现方法还需要根据实际情况进行调整,但是我们通过这个例子可以清晰地了解到管道通信的基础原理和实现方法,希望能够帮到您。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值