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;
}
时间: 2024-10-12 07:38:53

Linux 进程与线程四(加锁--解锁)的相关文章

Linux进程或线程绑定到CPU

Linux进程或线程绑定到CPU 为了让程序拥有更好的性能,有时候需要将进程或线程绑定到特定的CPU,这样可以减少调度的开销和保护关键进程或线程. 进程绑定到CPU Linux提供一个接口,可以将进程绑定到特定的CPU: #include <sched.h> int sched_setaffinity(pid_t pid, size_t cpusetsize, const cpu_set_t *mask); int sched_getaffinity(pid_t pid, size_t cpu

linux进程管理(四)

[教程主题]:进程管理 [1]进程介绍 程序和进程 程序是为了完成某种任务而设计的软件,比如OpenOffice是程序.什么是进程呢?进程就是运行中的程序. 一个运行着的程序,可能有多个进程. 比如自学it网所用的WWW服务器是apache服务器,当管理员启动服务后,可能会有好多人来访问,也就是说许多用户来同时请求httpd服务,apache服务器将会创建有多个httpd进程来对其进行服务. 进程分类: 进程一般分为交互进程.批处理进程和守护进程三类. 值得一提的是守护进程总是活跃的,一般是后台

Linux 进程、线程运行在指定CPU核上

/******************************************************************************** * Linux 进程.线程运行在指定CPU核上 * 说明: * affinity参数决定了进程.线程是否可在CPU多核之间切换,当然,并不是说就不进行 * 线程切换. * * 2017-9-22 深圳 龙华樟坑村 曾剑锋 *********************************************************

linux 进程 VS 线程

在进行编程模型选择时,总是要对进程和线程的优缺点进行对比,才能做出决定.这里对常用的对比纬度进行了总结,如有新发现,我会更新. linux 进程 VS 线程

Linux进程和线程的比较

进程与线程 参考:http://www.cnblogs.com/blueclue/archive/2010/07/16/1778855.html 首先比较Linux进程和线程的创建的区别,以此展开: 创建进程:(1)调用fork(),为子进程新建内核栈.pthread_info和task_struct,复制父进程的大部分的参数,采用写时复制(copy-on-write)辅助父进程的资源,修改子进程如pid.ppid等重要资源.(2)调用exec()为子进程分配地址空间,载入执行程序. 创建线程:

探究Linux进程及线程堆栈专题&lt;一&gt;

“你定义了那么多全局变量,系统才给你分配了几百KB,这样做是不是太耗内存了?”,一同学问道. 老早就听说嵌入式系统各种资源有限啊,不能分配大空间啊要注意节约资源之类的(...貌似米神4的配置要完爆我的thinkpad了...).那是不是全局变量的使用真的会占用很大系统内存,而系统真的才分配几百KB空间给我呢? 我不信,所以我要尝试一下: 全局变量,肯定是要占用内存的,但无论是不是全局变量,只要是已定义的变量都会占用内存,这个和是否是全局的没啥关系,只是占用的区域不一样而已(详见APUE存储器安排

linux进程、线程(or子进程)、资源占用查看

#  linux进程.线程(or子进程).资源占用查看 查看进程: ps -ef | more  (-e:所有进程,-f:全格式) ++++++++++++++++++++++++++++++++++++ + UID :用户ID                     + + PID :进程ID                           + + PPID :父进程ID                                                 + + C :CPU占

Linux进程与线程的区别

cnyinlinux 本文较长,耐心阅读,必有收获! 进程与线程的区别,早已经成为了经典问题.自线程概念诞生起,关于这个问题的讨论就没有停止过.无论是初级程序员,还是资深专家,都应该考虑过这个问题,只是层次角度不同罢了.一般程序员而言,搞清楚二者的概念,在工作实际中去运用成为了焦点.而资深工程师则在考虑系统层面如何实现两种技术及其各自的性能和实现代价.以至于到今天,Linux内核还在持续更新完善(关于进程和线程的实现模块也是内核完善的任务之一). 本文将以一个从事Linux平台系统开发的程序员角

操作系统:Linux进程与线程

这里是一部分内容,还会做修改. 一:目的及内容 学习fork(),exec,pthread库函数的使用,阅读源码,分析fork,exec,pthread_create函数的机理 代码实现: 进程A创建子进程B 子进程B与父进程A分别对应不同的可执行体:A打印Hello world,B实现sum累加 进程B具有三线程,主线程创建新的线程1实现sum累加(从1到参数x),线程2监控输入参数x 若输入x是非负整数,线程1开始计算:如果线程1正在计算前次程序,线程2的输入非负整数和最近一次的又不同,线程