ok6410学习笔记(3.并发和竞态)

       学习资料:1.国嵌视频和ppt    2.操作系统精髓与设计原理 (机械工业出版社)

       主要知识点:1.自旋锁(spinlock)   2.信号量(semaphore)    具体函数详细见ppt和操作系统P195~P199

       思考:1.内核的信号量和应用层的信号量(见国嵌应用开发进程通信)有什么关系和区别(这里涉及内核中进程间通信与用户空间进程通信的通信方式)

                   2.fread为c语言标准库中的函数   read为linux系统函数   他们调用底层operation的方式一样吗?

                      注:fread(buf,sizeof(buf),1,fp)              number = read(handle, buffer ,n)   我觉得是fread先找到系统调用read再想上节说的那样找operation

        国嵌练习:应用层用一个子进程和一个父进程分别去对字符设备进行写操作     通过信号量保证资源竟态问题    我尝试把驱动函数中关于信号量的函数去掉结果是读取的结果乱了(字符间的顺序变了),如果有信号量则读取不会乱。但是这个程序偶尔在红帽企业版5下面也会使系统死掉,原因未明,以后在学习中找到了再更新上来吧。但在ok6410开发班上不会导致系统崩溃。

                           /* 初始化信号量 */
                          sema_init(&mem_devp[i].sem, 1);

                          /* 获取信号量 */
                          if (down_interruptible(&dev->sem))
                          return -ERESTARTSYS;

                          /* 释放信号量 */
                          up(&dev->sem);    

       应用层代码:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>

int main(void)
{
	int fd, ret;
	char buf[256];
    printf("Two processes are writing ...\n");

    if (-1==(ret=fork())) 
    {
        printf("fork() error\n");
        _exit(EXIT_FAILURE);
    } 
    else if (0 == ret) 
    	{   /*child process*/ 
	        if (-1==(fd=open ("/dev/memdev0", O_RDWR))) 
	        {
	            printf("open() error");
	            _exit(EXIT_FAILURE);
        	}
        strcpy(buf, "Here is the CHILD writing ...");
        printf("Child write: %s\n", buf);
        write(fd, buf, strlen(buf)); 
        close(fd);
        _exit(EXIT_SUCCESS);
	} 
	else {                 /*father process*/
	        if (-1==(fd=open ("/dev/memdev0", O_RDWR))) 
	        {
	            printf("open() error");
	            _exit(EXIT_FAILURE);
	        }
	        strcpy(buf, "The semaphore is nesessory in the memdev driver ...");
	        printf("Father write: %s\n", buf);
	        write(fd, buf, strlen(buf)); 
	        close(fd);
	        wait(NULL); 
  	  }
    
    if (-1==(fd=open ("/dev/memdev0", O_RDWR))) 
    {
        printf("open() error");
        _exit(EXIT_FAILURE);
    }
    memset(buf, 0, sizeof(buf));
    read(fd, buf, sizeof(buf));
    printf ("At last, the content in memdev is: %s\n", buf);

	close(fd);
	return 0;	
}

日后补充:1.以后的驱动学习中一定要特别注意内核态编程和用户态编程的关系和区别,类比学习。

                    2.内核态的信号量和用户态的信号量的区别,原理机制类似,一个是在应用层,一个是在内核层,具体应用层和内核层的区别还不太理解,但是用途不同,如用户态的信号量确保设备节点的竟态问题,而内核层的信号量确保下面的设备(如串口、led)的竟态问题。

                    3.内核态信号量和阻塞设备驱动的关系,信号量是看设备有没有可以使用的,而阻塞设备驱动是看设备有没有符合要求的。例如:有3个串口,信号量是看3个串口有没有没被占用的,而阻塞设备驱动是判断这个没被占用的串口能不能发送数据,即寄存器有没有准备好。

                       

你可能感兴趣的:(ok6410学习笔记(3.并发和竞态))