热门内容

公众号"MAKE1"

获取行业最新资讯

请扫码添加

专业客服企业微信

互斥锁

简介

互斥锁

互斥量mutex的简单使用

#include <pthread.h>

int pthread_mutex_init(pthread_mutex_t *restrict mutex, const pthread_mutex_t *restrict attr); //初始化mutex

int pthread_mutex_destroy(pthread_mutex_t *mutex); //如果mutex是动态分配的,则释放内存前调用此函数。

int pthread_mutex_lock(pthread_mutex_t *mutex); //加锁

int pthread_mutex_trylock(pthread_mutex_t *mutex); //若已有其他线程占用锁,则返回EBUSY,否则返回0,不阻塞。

int pthread_mutex_unlock(pthread_mutex_t *mutex); //解锁

 1 #include <stdlib.h>
 2 #include <stdio.h>
 3 #include <unistd.h>
 4 #include <pthread.h>
 5 #include <errno.h>
 6 
 7int a = 100;
 8int b = 200;
 9
10pthread_mutex_t lock;  -----定义
11
12void * threadA()
13{
14  pthread_mutex_lock(&lock);------加锁
15     printf("thread A got lock!n");
16  a -= 50;
17  sleep(3);        //如果不加锁,threadB输出会是50和20018
    b += 50;        //加锁后会sleep 3秒后,并为b加上50 threadB才能打印19 
    pthread_mutex_unlock(&lock);-----解锁
20  printf("thread A released the lock!n");
21     a -= 50;
22}
23
24void * threadC()
25{    
26     sleep(1);
27while(pthread_mutex_trylock(&lock) == EBUSY) //轮询直到获得锁
28    {
29         printf("thread C is trying to get lock!n");
30         usleep(100000);
31    }
32     printf("thread C got the lock!n");
33     a = 1000;
34     b = 2000;
35pthread_mutex_unlock(&lock);
36     printf("thread C released the lock!n");
37
38}
39
40void * threadB()
41{
42     sleep(2);                //让threadA能先执行
43pthread_mutex_lock(&lock);
44     printf("thread B got the lock! a=%d b=%dn", a, b);
45pthread_mutex_unlock(&lock);
46     printf("thread B released the lock!n", a, b);
47}
4849int main()
50{
51    pthread_t tida, tidb, tidc;
52pthread_mutex_init(&lock, NULL); -----初始化锁53     pthread_create(&tida, NULL, threadA, NULL);
54     pthread_create(&tidb, NULL, threadB, NULL);
55     pthread_create(&tidc, NULL, threadC, NULL);
56    pthread_join(tida, NULL);
57    pthread_join(tidb, NULL);
58    pthread_join(tidc, NULL);
59return0;
60 }

 

Linux内核互斥锁--mutex:

 

具体参见linux/kernel/mutex.c

包含头文件:

include <linux/mutex.h >
使用形式:

 

 

struct mutex mutex;

mutex_init(&mutex); /*定义*/

...


mutex_lock(&mutex); /*获取互斥锁*/

... /*临界资源*/

mutex_unlock(&mutex); /*释放互斥锁*/

 

EG:

int frizz_ioctl_hardware_download_firmware( char *name )

{

 

struct file *filep;

int read_file_size;

unsigned int header;

int modified_ram_size;

int data_size;

unsigned int cmd;

unsigned int ram_addr;

unsigned char *write_ram_data;

unsigned char *read_ram_data;

unsigned char read_data[4];

int i;

struct mutex lock;

mutex_init(&lock);

mutex_lock(&lock);//增加自锁

frizz_gpio_output(1);//sensor HUB GPIO3 拉高

I( "frizz_ioctl_hardware_download_firmware(%s)n", name );

filep = filp_open( name, O_RDONLY | O_LARGEFILE, 0 );

if( IS_ERR( filep ) ) {

printk( "can't open %s n", name );

return 1;

}

frizz_ioctl_hardware_stall();

 

do {

read_file( filep, read_data, 1, &read_file_size );

header = read_data[0];

if( header == 0xC9 ) {

//get file data size. remove cmd (2byte) and ram addr (4byte)

read_file( filep, read_data, 3, &read_file_size );

data_size = ( ( read_data[0] << 16 ) | ( read_data[1] << 8 ) | ( read_data[2] ) ) - 6;

 

//get frizz command (command of writting ram)

read_file( filep, read_data, 2, &read_file_size );

cmd = ( read_data[0] << 8 ) | ( read_data[1] );

 

//get ram address

read_file( filep, read_data, 4, &read_file_size );

ram_addr = ( read_data[0] << 24 ) | ( read_data[1] << 16 ) | ( read_data[2] << 8 ) | ( read_data[3] );

 

//keep memory

write_ram_data = kmalloc( data_size, GFP_KERNEL | GFP_DMA );

read_file( filep, write_ram_data, data_size, &read_file_size );

 

modified_ram_size = data_size + 3;

modified_ram_size &= 0xFFFFFFFC;

 

D( "writing data to ram start. ram_addr=%u, write_ram_data=%p, modified_ram_size=%dn", ram_addr, write_ram_data, modified_ram_size );

serial_write_reg_ram_data( RAM_ADDR_REG_ADDR, ram_addr, write_ram_data, modified_ram_size );

D( "writing data to ram start endn" );

 

//keep memory (verify)

read_ram_data = kmalloc( data_size, GFP_KERNEL | GFP_DMA );

 

D( "serial_write_reg_32 start. ram_addr=%un", ram_addr );

serial_write_reg_32( RAM_ADDR_REG_ADDR, ram_addr );

serial_read_reg_array( RAM_DATA_REG_ADDR, read_ram_data, modified_ram_size );

D( "serial_read_reg_array end. read_ram_data=%p, modified_ram_size=%dn", read_ram_data, modified_ram_size );

 

for( i = 0; i < modified_ram_size; i++ ) {

if( write_ram_data[i] != read_ram_data[i] ) {

D( "firmware download i=%d, write_ram_data[i](=%d) != read_ram_data[i](=%d)n", i, write_ram_data[i], read_ram_data[i] );

break;

}

}

 

if( i == modified_ram_size ) {

D( "%s: Verify Success. start address %x n", DRIVER_NAME, ram_addr );

} else {

D( "%s: [%d] write ram data %x read ram data %xn", DRIVER_NAME, i, write_ram_data[i], read_ram_data[i] );

D( "%s: Verify Failed. start address %x n", DRIVER_NAME, ram_addr );

}

 

kfree( write_ram_data );

kfree( read_ram_data );

 

} else if( header == 0xED00 ) {

 

//don't execute command and skip data.

read_file( filep, read_data, 2, &read_file_size );

data_size = ( ( read_data[0] << 8 ) | ( read_data[1] ) );

 

read_file( filep, read_data, 2, &read_file_size );

cmd = ( read_data[0] << 8 ) | ( read_data[1] );

 

read_file( filep, read_data, 4, &read_file_size );

}

 

} while( read_file_size != 0 );

 

 

frizz_ioctl_software_reset();

 

mdelay( 1000 );

serial_read_fifo_CNR();

 

#if defined(FRIZZ_LOW_POWER_MODE_GPIO)

 

//set low clock mode

serial_write_reg_32( MODE_REG_ADDR, 0x0 );

 

//send low power command

{

packet_t packet;

packet.header.w = 0xFF81FF01;

packet.data[0] = 0x09010300;

create_frizz_workqueue( ( void* )&packet );

}

 

#endif

 

frizz_ioctl_enable_gpio_interrupt();

 

irq_set_irq_type( frizz_irq, IRQF_SHARED | IRQF_TRIGGER_LOW );

 

frizz_ioctl_sensor_get_version( SENSOR_TYPE_PDR );

filp_close( filep, NULL );

 

frizz_gpio_output(0);//Sensoer HUB GPIO3拉低

mutex_unlock(&lock);// jimmy 增加自锁

 

return 0;

}

0
 条评论
相关内容推荐