Linux 进程与线程四(加锁--解锁)

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Linux 进程与线程四(加锁--解锁)相关的知识,希望对你有一定的参考价值。

线程共享进程的内存空间,打开的文件描述符,全局变量。
当有多个线程同事访问一块内存空间或者一个变量、一个文件描述符,如果不加控制,那么可能会出现意想不到的结果。
原子操作
对于我们的高级语言(C语言,java,c#),普通的一句代码一般都是由多条汇编语句组成,计算机CPU每次所执行的都是一条汇编指令
,一条汇编指令是无法再次拆分的,所以计算机CPU同一时间只能执行一条汇编指令就是一个原子操作。
互斥(mutex)是相互排斥的意思,它是一种锁或者信号灯。
互斥用来保护多个线程共享的数据和结构不会被同事修改,一个互斥锁只能有两个状态
--locked    加锁
--unlocked    解锁
加锁后互斥不让其他线程访问。
任何时刻只能有一个线程来掌握某个互斥上锁。
锁操作是一个原子操作
一个线程如果试图在一个已经加锁的互斥上再加锁,这个线程会被挂起,,直到加锁的线程释放掉互斥锁为止。
强调:加锁解锁针对的是pthread_mutex_t类型的变量,只要有一个地方加锁,哪怕在别的线程中有加锁代码,那个线程也会被挂起,
只有当pthread_mutex_t类型的变量解锁后,其他的线程才可以继续对pthread_mutex_t类型的变量加锁。 注意:互斥情况下,如果将某个正在加锁占用资源的进程用pthread_cancel函数取消掉,可能产生死锁。
//线程加锁--pthread_mutex_lock
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include <unistd.h>
#include <errno.h>
#include <pthread.h>

//定义一个全局的互斥变量
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
int count = 0;

void * MyFunc(void * arg)
{
    if (arg == NULL)
    {
        printf("param is not allow NULL!\n");
        return NULL;
    }
    //加锁--所有线程都能访问的全局变量加锁
    pthread_mutex_lock(&mutex);
    int * pnumx = (int *) arg;
    int i = 0;
    while (i < 10)
    {
        printf("thread%d count=%d\n", *pnumx, count++);
        sleep(1);
        i++;
    }
    //解锁
    pthread_mutex_unlock(&mutex);
    return NULL;
}

void * MyFunc2(void * arg)
{
    if (arg == NULL)
    {
        printf("param is not allow NULL!\n");
        return NULL;
    }
    //这个锁和myfunc中的锁是同一个锁,myfunc被锁,这里也会被锁
    pthread_mutex_lock(&mutex);
    int * pnumx = (int *) arg;
    int i = 0;
    while (i < 10)
    {
        printf("thread%d count=%d\n", *pnumx, count++);
        sleep(1);
        i++;
    }
    //解锁
    pthread_mutex_unlock(&mutex);
    return NULL;
}

int main(int arg, char * args[])
{
    pthread_t thr1, thr2;
    pthread_attr_t attr;
    pthread_attr_init(&attr);
    //设置进程为可分离状态
    pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
    int a = 1, b = 2;
    //创建线程
    if (pthread_create(&thr1, &attr, MyFunc, &a) != 0)
    {
        printf("create thread is failed ! error message :%s\n",
                strerror(errno));
        return -1;
    }
    //释放进程属性对象
    pthread_attr_destroy(&attr);
    if (pthread_create(&thr2, NULL, MyFunc, &b) != 0)
    {
        printf("create thread is failed ! error message :%s\n",
                strerror(errno));
        return -1;
    }
    pthread_join(thr2, NULL);
    printf("main end\n");
    return 0;
}

 

以上是关于Linux 进程与线程四(加锁--解锁)的主要内容,如果未能解决你的问题,请参考以下文章

Linux 网络协议栈之内核锁—— 互斥锁读写锁 自旋锁和RCU锁简述

6.5 linux内核互斥锁

linux C语言 多线程竞争(加锁解锁 pthread_mutex_tpthread_mutex_lock()pthread_mutex_unlock() 可解决)

linux C语言 多线程竞争(加锁解锁 pthread_mutex_tpthread_mutex_lock()pthread_mutex_unlock() 可解决)

Linux系统编程 多线程

Linux系统编程 多线程