IO进程线程day5

IO进程线程day5_第1张图片

1.实现互斥机制

#include 

char buf[128];            //全局数组,临界资源

//1、创建一个互斥锁
pthread_mutex_t mutex;

//定义分支线程
void *task(void *arg)
{
    while(1)
    {
        //3、获取锁资源
        pthread_mutex_lock(&mutex);

        printf("分支线程中:buf = %s\n", buf);
        strcpy(buf, "I love China\n");

        //4、释放锁资源
        pthread_mutex_unlock(&mutex);
    }
}


int main(int argc, const char *argv[])
{
    //定义线程号变量
    pthread_t tid;

    //2、初始化互斥锁
    pthread_mutex_init(&mutex, NULL);

    //创建线程
    if(pthread_create(&tid, NULL, task, NULL) != 0)
    {
        printf("tid create error\n");
        return -1;
    }

    //主线程
    while(1)
    {
        //3、获取锁资源
        pthread_mutex_lock(&mutex);

        printf("主线程中buf = %s\n", buf);       //访问临界资源
        strcpy(buf, "hello world\n");  

        //4、释放锁资源
        pthread_mutex_unlock(&mutex);
    }
    


    pthread_join(tid, NULL);         //阻塞回收线程资源
    //5、销毁锁资源
    pthread_mutex_destroy(&mutex);

    return 0;
}

2.实现同步机制

#include 

//1、创建一个无名信号量
sem_t sem;

//生产者线程
void *task1(void *arg)
{
    while(1)
    {
        sleep(2);
        printf("我生产了一辆特斯拉\n");

        //4、释放资源
        sem_post(&sem);
    }
}

//消费者线程
void *task2(void *arg)
{
    while(1)
    {
        //3、申请资源,如果没有资源,则在该处阻塞
        sem_wait(&sem);

        printf("我消费了一辆特斯拉\n");
    }
}

int main(int argc, const char *argv[])
{
    //创建两个线程
    pthread_t tid1,tid2;

    //2、初始化无名信号量
    sem_init(&sem, 0, 0);
    //第一个0:表示用于线程之间的通信
    //第二个0:表示value初始值为0

    //创建生产者线程
    if(pthread_create(&tid1, NULL, task1, NULL) != 0)
    {
        printf("tid1 create error\n");
        return -1;
    }
    //创建消费者线程
    if(pthread_create(&tid2, NULL, task2, NULL) != 0)
    {
        printf("tid2 create error\n");
        return -1;
    }


    //主线程回收资源
    pthread_join(tid1, NULL);
    pthread_join(tid2, NULL);

    //5、销毁无名信号量
    sem_destroy(&sem);

    return 0;
}

3.使用三个线程完成两个文件的拷贝,线程1完成拷贝前一半,线程2完成拷贝后一半,主线程回收两个分支线程的资源

  1 #include 
  2 sem_t sem;
  3 struct Info
  4 {
  5     int fd1;
  6     int fd2;
  7     int size;
  8 };
  9
 10 void *task1(void *buf)
 11 {
 12     //不断得将源文件中的内容读出,并写入的目标文件中                                                                                                                                                       
 13     //直到源文件读取一半结束
 14     char buf1[1] = "";
 15     int count=0;
 16     lseek(((struct Info*)buf)->fd1,0,SEEK_SET);
 17     while(1)
 18     {
 19         memset(buf1, 0, sizeof(buf1));    //将容器清空
 20         int res = read(((struct Info*)buf)->fd1, buf1, sizeof(buf1));   //从源文件中读取数据
 21         count+=res;
 22         //对读取的数据个数进行判断
 23         if(count>((struct Info*)buf)->size/2)
 24         {
 25             break;
 26         }
 27         write(((struct Info*)buf)->fd2, buf1, res);     //将数据写入目标文件
 28     }sem_post(&sem);
 29     pthread_exit(NULL);
 30 }
 31 void *task2(void *buf)
 32 {
 33     sem_wait(&sem);
 34     lseek(((struct Info*)buf)->fd1,(((struct Info *)buf)->size)/2,SEEK_SET);
 35     //不断得将源文件中的内容读出,并写入的目标文件中
 36     //直到源文件读取后一半结束
 37     char buf2[128] = "";
 38     while(1)
 39     {
 40         memset(buf2, 0, sizeof(buf2));    //将容器清空
 41         int res = read(((struct Info *)buf)->fd1, buf2, sizeof(buf2));   //从源文件中读取数据
 42         //对读取的数据个数进行判断
 43         if(res==0)
 44         {
 45             break;
 46         }
 47         write(((struct Info*)buf)->fd2, buf2, res);     //将数据写入目标文件
 48     }
 49     pthread_exit(NULL);
 50 }
 51 int main(int argc, const char *argv[])
 52 {
 53     //判断传入的文件个数
 54     if(argc != 3)
 55     {
 56         printf("input file error\n");
 57         printf("usage:./a.out srcfile dstfile\n");
 58         return -1;
 59     }
 60     //定义文件描述符变量
 61     int fd1, fd2;
 62     //以只读的形式打开源文件
 63     if((fd1 = open(argv[1], O_RDONLY)) ==-1)
 64     {
 65         perror("open srcfile error");
 66         return -1;
 67     }
 68     //以只写的形式打开目标文件
 69     if((fd2 = open(argv[2], O_WRONLY|O_CREAT|O_TRUNC, 0664)) ==-1)
 70     {
 71         perror("open dstfile error");
 72         return -1;
 73     }
 74     sem_init(&sem, 0, 0);
 75     unsigned int size;
 76     size = lseek(fd1, 0, SEEK_END);
 77     struct Info buf = {fd1, fd2, size};
 78     //定义一个线程号变量
 79     pthread_t tid1,tid2;
 80     //创建出一个分支线程
 81     if(pthread_create(&tid1, NULL, task1, &buf) != 0)
 82     {
 83         printf("tid create error\n");
 84         return -1;
 85     }
 86     if(pthread_create(&tid2, NULL, task2, &buf) != 0)
 87     {
 88         printf("tid create error\n");
 89         return -1;
 90     }
 91     pthread_join(tid1, NULL);
 92     pthread_join(tid2, NULL);
 93     sem_destroy(&sem);
 94     close(fd1);
 95     close(fd2);
 96     return 0;
 97 }

4.使用三个线程完成:线程1输出字符'A',线程2输出字符'B',线程3输出字符'C',要求输出结果为:ABCABCABCABCABC...

#include 
sem_t sem1,sem2,sem3;//无名信号量

void *task1(void *arg)
{
	while(1)
	{
		sem_wait(&sem1);//询问当前任务的无名信号量(下同)
		putchar('A');
		fflush(stdout);//刷新缓冲区(下同)
		sleep(1);
		sem_post(&sem2);//将下一个任务的无名信号量改变为1(下同)
	}
}
void *task2(void *arg)
{
	while(1)
	{
		sem_wait(&sem2);
		putchar('B');
		fflush(stdout);
		sleep(1);
		sem_post(&sem3);
	}
}
void *task3(void *arg)
{
	while(1)
	{
		sem_wait(&sem3);
		putchar('C');
		fflush(stdout);
		sleep(1);
		sem_post(&sem1);
	}
}
int main(int argc, const char *argv[])
{
	//无名信号量初始化
	sem_init(&sem1,0,1);
	sem_init(&sem2,0,0);
	sem_init(&sem3,0,0);
	//定义三个线程
	pthread_t tid1,tid2,tid3;
	if(pthread_create(&tid1,NULL,task1,NULL)!=0)
	{
		printf("error1\n");
		return -1;
	}
	if(pthread_create(&tid2,NULL,task2,NULL)!=0)
	{
		printf("error2\n");
		return -1;
	}
	if(pthread_create(&tid3,NULL,task3,NULL)!=0)
	{
		printf("error3\n");
		return -1;
	}
	//进程收尸
	pthread_join(tid1,NULL);
	pthread_join(tid2,NULL);
	pthread_join(tid3,NULL);
	return 0;
}

你可能感兴趣的:(嵌入式学习-IO进程线程,c语言)