精华内容
下载资源
问答
  • C语言中多线程数据共享问题
    千次阅读
    2019-04-20 14:39:20

    C语言中多线程之间共享全局变量data段数据实例(和多进程之间相反,多进程之间的全局变量不共享,每一个进程有独自的0到4G的地址空间)

      2 #include <string.h>
      3 #include <unistd.h>
      4 #include <pthread.h>
      5 
      6 
      7 
      8 int var = 100;
      9 
     10 void* tfn(void* arg)
     11 {
     12         var = 200;
     13         printf("pthread\n");
     14         return NULL;
     15 }
     16 
     17 int main()
     18 {
     19         printf("before pthread_c var = %d\n",var);
     20         pthread_t tid;
     21         pthread_create(&tid,NULL,tfn,NULL);
     22         sleep(1);
     23         printf("after pthread_create var = %d\n",var);
     24         return 0;
     25 }

     

     

    更多相关内容
  • 多线程之间共享数据的方式探讨

    千次阅读 2018-09-22 09:50:43
    多线程之间共享数据的方式探讨 方式一:代码一致 如果每个线程执行的代码相同,可以用一个Runnable对象,这个Runnable对象中存放那个共享数据(卖票系统可以这样做)。 public class MultiThreadShareData { ...

    多线程之间共享数据的方式探讨

    方式一:代码一致

    • 如果每个线程执行的代码相同,可以用一个 Runnable 对象,这个 Runnable 对象中存放那个共享数据(卖票系统可以这样做)。
    public class MultiThreadShareData {
        public static void main(String[] args) {
            MyShareData shareData=new MyShareData();
            //放入不同的线程中
            new Thread(shareData).start();
    
            new Thread(shareData).start();
    
        }
    }
    
    class MyShareData implements Runnable {
            // 共享的数据
            private int count = 100;
    
            @Override
            public void run() {
                while (count > 0) {
                    synchronized (this) {
                        if (count > 0) {
                            count--;
                            System.out.println(Thread.currentThread().getName() + " 减了1,count还剩:" + count);
                        }
    
                    }
    
                }
            }
        }

     

    方式二:代码不一致

    • 如果每个线程执行的代码不同时,就需要不同的 Runnable 对象:

    a. 将共享数据封装在一个对象中,然后将这个对象逐一传递给各个 Runnable 对象,每个线程对共享数据操作的方法也分配到这个对象中,这样容易实现针对该数据进行的各个操作的互斥通信。

    public class MultiThreadShareData {
    
        private int shareData=0;
    
        public static void main(String[] args) {
            ShareData data = new ShareData();
    
            new Thread(new MyRunnable1(data)).start();
    
            new Thread(new MyRunnable2(data)).start();
        }
    
    }
    
    class MyRunnable1 implements Runnable{
    
        private ShareData data;
    
        public MyRunnable1(ShareData data){
            this.data=data;
        }
    
        @Override
        public void run() {
            for(int i=0;i<100;i++){
                //对数据进行增加
                this.data.increment();
            }
        }
    }
    
    class MyRunnable2 implements Runnable{
    
        private ShareData data;
    
        public MyRunnable2(ShareData data){
            this.data=data;
        }
    
        @Override
        public void run() {
            for(int i=0;i<100;i++){
                //对数据进行减少
                this.data.decrement();
            }
        }
    }
    
    /**
     将共享的数据封装成一个类
    */
    class ShareData{
        //共享数据
        private int j=0;
    
        public synchronized void increment(){
            this.j++;
            System.out.println(Thread.currentThread().getName()+":j增加了1后j="+j);
        }
    
        public synchronized void decrement() {
            this.j--;
            System.out.println(Thread.currentThread().getName()+":j减少了1后j="+j);
        }
        public int getJ() {
            return j;
        }
    }

    b. 将 Runnable 对象作为某一个类的内部类,共享数据作为这个外部类的成员变量,每个线程对共享数据的操作方法也分配到外部类中,实现共享数据的互斥和通信操作,作为内部类的各个 Runnable 对象调用外部类的这些方法。

    public class MultiThreadShareData {
    
        private int shareData=0;
    
        public static void main(String[] args) {
            MultiThreadShareData m=new MultiThreadShareData();
            //初始化Runnable对象
            MyRunnable1 myRunnable1 = m.new MyRunnable1();
            MyRunnable2 myRunnable2=m.new MyRunnable2();
    
            //开启线程
            new Thread(myRunnable1).start();
    
            new Thread(myRunnable2).start();
        }
    
        private synchronized void increment(){
            this.shareData++;
            System.out.println(Thread.currentThread().getName()+":shareData增加了1后shareData="+shareData);
        }
    
        private synchronized void decrement() {
            this.shareData--;
            System.out.println(Thread.currentThread().getName()+":shareData减少了1后shareData="+shareData);
        }
    
        /**
         * 作为内部类的Runnable对象
         */
        class MyRunnable1 implements Runnable{
    
            @Override
            public void run() {
                for(int i=0;i<100;i++){
                    increment();
                }
            }
        }
    
        class MyRunnable2 implements Runnable{
    
            @Override
            public void run() {
                for(int i=0;i<100;i++){
                    decrement();
                }
            }
        }
    }

    c. 以上两种方法的组合:将共享数据封装到一个对象中,每个线程对共享数据的操作方法也分配到对象中,对象作为外部类的成员变量或方法中的局部变量,每个线程的 Runnable 作为成员内部类或局部内部类。

     public class MultiThreadShareData {
       public static void main(String[] args) {
    
           ShareData data = new ShareData();
    
           new Thread(()->{
               for(int i=0;i<100;i++){
                   data.increment();
               }
           }).start();
    
           new Thread(()->{
               for (int j=0;j<100;j++) {
                   data.decrement();
               }
           }).start();
       }
    
    }
    
    /**
    封装共享数据的对象
    */
    class ShareData{
       //共享数据
       private int j=0;
    
       /**
        对共享数据进行操作的方法
       */
       public synchronized void increment(){
           this.j++;
           System.out.println(Thread.currentThread().getName()+":j增加了1后j="+j);
       }
    
       public synchronized void decrement() {
           this.j--;
           System.out.println(Thread.currentThread().getName()+":j减少了1后j="+j);
       }
    
       public int getJ() {
           return j;
       }
    }

    总之, 要同步互斥的几段代码最好放在几个独立的方法中,这些方法再放入一个类中,这样比较容易实现它们之间的同步互斥和通信。

    展开全文
  • 多线程线程资源共享问题

    千次阅读 2017-12-01 18:25:11
    多线程的环境下, 由于公共资源可能会被多个线程共享, 也就是多个线程可能会操作( 增、删、改等 )同一资源. 当多个线程操作同一块资源时, 很容易导致数据错乱或发生数据安全问题, 即: 数据有可能丢失, 有可能增加...

    简介

    在多线程的环境下, 由于公共资源可能会被多个线程共享, 也就是多个线程可能会操作( 增、删、改等 )同一资源.
    当多个线程操作同一块资源时, 很容易导致数据错乱或发生数据安全问题, 即:
    数据有可能丢失, 有可能增加, 有可能错乱.

    资源共享经典问题–>卖票

    逻辑伪代码:
    if( 余票 > 0 )
    ……余票-1
    else
    ……提示无票

    代码

    Swift

    var votes = 10
    
    override func viewDidLoad() {
        super.viewDidLoad()
        // 售票
        self.saleTickets()
    }
    
    @objc func saleTickets() {
        while true {
            // 模拟耗时操作
            Thread.sleep(forTimeInterval: 1.0)
            if(self.votes > 0) {
                self.votes = self.votes - 1
                print(Thread.current.description + "  余票数为 " + self.votes.description)
            }
            else {
                print(Thread.current.description + "  无票")
                break;
            }
        }
    }

    OC

    // 票数
    @property (nonatomic, assign) int votes;
    
    - (void)viewDidLoad {
        [super viewDidLoad];
        self.tickets = 10;
        // 售票
        [self saleTickets];
    }
    
    - (void)saleTickets
    {
        while(YES)
        {
            // 模拟耗时操作
            [NSThread sleepForTimeInterval:1.0];
            if(self.votes > 0)
            {
                self.votes--;
                NSLog(@"余票数为%d", self.votes);
            }
            else
            {
                NSLog(@"无票");
                break;
            }
        }
    }

    问题

    这时候我们在单线程上面运行是没问题的, 但是当有多个售票员(子线程)在卖票(共同访问同一个数据)的时候, 就会出现以下的情况:
    代码:
    OC

    // 售票员1
    NSThread *conductor1 = [[NSThread alloc]initWithTarget:self selector:@selector(saleTickets) object:nil];
    conductor1.name = @"售票员1";
    [conductor1 start];
    
    // 售票员2
    NSThread *conductor2 = [[NSThread alloc]initWithTarget:self selector:@selector(saleTickets) object:nil];
    conductor2.name = @"售票员2";
    [conductor2 start];

    Swift

    // 售票员1
    let conductor1 = Thread.init(target: self, selector: #selector(saleTickets), object: nil)
    conductor1.name = "售票员1"
    conductor1.start()
    
    // 售票员2
    let conductor2 = Thread.init(target: self, selector: #selector(saleTickets), object: nil)
    conductor2.name = "售票员2"
    conductor2.start()

    打印:
    这里写图片描述

    PS: 笔者记得两三年前刚接触iOS的多线程的时候, 测试有次测得余票数是-1的, 现在侧很久都没发现有-1的情况. 有兴趣的大兄弟可以试试

    原因

    这里写图片描述

    解决

    在共同资源( 票数 )被访问( 确切说是准备变化 )的时候( 如上图线程1写入时 ), 该资源只能被一个线程操作.
    这时, 我们就可以使用互斥锁等保证被锁定的代码( 资源 ), 同一时间, 只能有一个线程可以操作.

    代码修改:
    Swift

    @objc func saleTickets() {
        while true {
            Thread.sleep(forTimeInterval: 0.1)
            /// 添加互斥锁
            /// 由于互斥锁为了数据安全会牺牲性能, 所有互斥锁的范围一定要尽可能地小
            /// 参数: 可以使任意的继承自基类NSObject的对象
            /// 但是, 这个参数一定要确保, 互斥的其他线程认识这把锁.
            /// 由于self本身就是一个全局变量, 所以一般我们都直接给self
            objc_sync_enter(self)
            if(self.votes > 0) {
                self.votes = self.votes - 1
                print(Thread.current.description + "  余票数为 " + self.votes.description)
            }
            else {
                print(Thread.current.description + "  无票, 当前票数为" + self.votes.description)
                break;
            }
            objc_sync_exit(self) // 记得退出互斥锁
        }
    }

    OC

    - (void)saleTickets
    {
        while(YES)
        {
            // 模拟耗时操作
            [NSThread sleepForTimeInterval:1.0];
            // 添加互斥锁
            @synchronized (self) 
            {
                if(self.votes > 0)
                {
                    self.votes--;
                    NSLog(@"余票数为%d", self.votes);
                }
                else
                {
                    NSLog(@"无票");
                    break;
                }
            }
        }
    }
    展开全文
  • Java:线程数据共享

    千次阅读 2018-11-09 23:51:07
    并发运行   线程中并发指一个时间段中多个线程都处于已启动但没有运行结束的状态。   多个线程之间默认并发运行,这种运行方式往往会出现交叉的情况。...使原本并发运行的多个...蓝框:多线程共享数据 红框...

    并发运行

     

    线程中并发指一个时间段中多个线程都处于已启动但没有运行结束的状态。

     

    多个线程之间默认并发运行,这种运行方式往往会出现交叉的情况。

     

     

     

    串行运行

     

    使原本并发运行的多个线程实现串行运行,即多线程间同步执行,需要通过对象锁机制来实现,synchronized就是一个利用锁实现线程同步的关键字。

     

    注:

    蓝框:多线程间共享的数据

    红框:synchronized对象锁:该对象锁是Java中创建的一个对象,该对象可由任意类创建,只要求所创建的对象在多个线程之间共享即可。如果对象锁为全局成员,为了保证该对象在多个线程间共享,该成员往往被private static final修饰。

     

    注:通过synchronized关键字实现了线程串行运行:一个线程执行完synchronized 代码块后另一个线程才执行,但是哪个线程先执行synchronized 代码块中的代码无法确定

     

    多线程同步原理

     

    为什么通过synchronized就能实现多线程间串行运行呢?

     

    1.synchronized括着的部分就是线程执行临界区,每次仅能有一个线程执行该临界区中的代码:当多个线程中的某个线程先拿到对象锁, 则该线程执行临界区内的代码,其他线程只能在临界区外部等待,当此线程执行完临界区中的代码后,在临界区外部等待的其他线程开始再次竞争以获取对象锁,进而执行临界区中的代码,但只能有一条线程“胜利”。

     

    2.临界区中的代码具有互斥性、唯一性和排它性:一个线程只有执行完临界区中的代码另一个线程才能执行。

     

     

    注:

    为什么这行代码60秒左右才会执行?

     

            显示器线程和时间线程共享lockObj对象,显示器线程优先进入启动状态,随后执行相应的run方法,当执行同步代码块时lockObj变量所代表的对象锁归显示器线程所有,进而创建时间线程并使之处于启动状态,此时有一下两种状态:

     

            1、时间线程马上进入执行状态,马上执行该时间线程run方法,可是由于此时lockObj变量所代表的对象锁被显示器线程持有,这时时间线程进入阻塞状态,显示器线程再次执行,然后执行sleep方法,显示器线程在继续持有对象锁的前提下也进入阻塞状态,60秒后显示器线程进入执行状态,随后显示器线程结束,对象锁被释放,进而时间线程开始执行,进而这行代码运行;

     

             2、时间线程并没有马上进入执行状态,显示器线程执行sleep方法,显示器线程在继续持有对象锁的前提下也进入阻塞状态,此时时间线程进入执行状态,执行该时间线程run方法,执行该方法中第一行输出代码,可是由于此时lockObj变量所代表的对象锁被显示器线程持有,所以时间线程并没有执行时间线程run方法内临界区中的代码,这时时间线程也进入阻塞状态,此时显示器和时间两条线程均进去阻塞状态,等待少于60秒的时间后,显示器线程进入运行状态,随后显示器线程结束,对象锁被释放,进而时间线程开始执行,进而这行代码运行;

     

    注:此时临界区中的代码无法实现串行执行,因为此时对象锁在线程1和线程2之间不共享。

     

    注:

    此时临界区中的代码依然无法实现串行执行,因为每一个独立线程拥有一个独立的对象锁——new CounterThread()

    要明白这两点:

    谁调用该run方法?——CounterThread类对象;

    谁执行该run方法?——正在执行的线程

     

    注:此时临界区中的代码无法实现串行执行,因为此时对象锁在线程1和线程2之间不共享。

     

    注:

    此时临界区中的代码依然无法实现串行执行,因为每一个独立线程拥有一个独立的对象锁——new CounterThread()

    要明白这两点:

    谁调用该run方法?——CounterThread类对象;

    谁执行该run方法?——正在执行的线程

     

    注:此时临界区中的代码可以实现串行执行,因为此时接口实现类对象充当了对象锁的功能,该对象锁在两个线程之间共享。

     

    synchronized关键字

     

    synchronized同步关键字有两种使用方式:

     

    1.声明同步方法:

     

     

    注:若为非静态同步方法,则多线程间共享调用该方法的对象;若为静态同步方法,则多线程之间同享调用该方法的类;

     

    2.同步代码块:

     

     

    注:this不能在静态方法中使用,此时括号中为类名.class“:此时多个线程之间共享该类对应的Class类对象(示例代码见代码2)。

     

    死锁

     

     注:

    1.如果有两个或两个以上的线程都访问了多个资源,而这些线程占用了一些资源的同时又在等待其它线程占用的资源,也就是说多个线程之间都持有了对方所需的资源,而又相互等待对方释放的资源,在这种情况下就会出现死锁。

     

    2.多个线程互相等待对方释放对象锁,此时就会出现死锁

     

     

     

     

     

     

     

     

     

     

     

    展开全文
  • 线程之间共享数据

    千次阅读 2018-10-10 22:18:38
    线程之间共享数据,首先想到的是将共享数据设置为全局变量,并且用static修饰,但是static修饰的变量是类变量,生命周期太长了,占用内存,本文将介绍三种方法实现线程之间共享数据。 方法一:线程对...
  • 本文主要介绍下ThreadLocal,重要的概念是线程范围内的数据共享 线程之间的数据不相互干扰,int data = 0;A线程取A线程的数据data,B线程取B线程的数据data。怎样才能使上例子完成?我们直接上例子吧 public ...
  • GIL(全局解释器锁)是C语言版本的Python解释器中专有的,GIL的存在让多线程的效率变低(哪个线程抢到锁,就执行哪个线程)。在IO密集型程序中,多线程依然比单线程效率高(GIL通过IO阻塞自动切换多线程)。 解决GIL(全局...
  • Qt线程共享数据

    千次阅读 2017-11-29 14:34:56
    数据共享注意点像 QString 等这些 Qt 本身定义的类型,直接传送即可。但如果自定义的类型想使用 signal/slot 来传递的话,则不能直接使用。 typedef unsigned short u16;以 u16 为例: 步骤: - 在类型定义完之后...
  • 如何在两个线程之间共享数据

    千次阅读 2020-10-26 21:52:39
    常用的实现多线程数据共享的方式有将数据抽象成一个类,并将对这个数据的操作封装在类的方法中;将Runnable对象作为一个类的内部类,将共享数据作为这个类的成员变量。 方法一 将数据抽象成一个类,并将对这个
  • 一、如果是每个线程都执行相同的代码,则可以使用同一个Runnable来实现共享public class MultiThreadShareData { public static void main(String[] args) { new Thread(new ShareData()).start(); new Thread...
  • 共享内存多线程数据交换(C++)

    热门讨论 2011-01-31 14:40:56
    前几天学习共享内存,和多线程应用写了个小程序,给初学者一点帮助
  • Java 线程之间共享数据

    千次阅读 2019-10-29 11:49:21
    线程之间共享数据,按照每个线程执行代码是否相同,我们可以采取不同的处理方式,这里通过简单的卖票示例说明了当每个线程执行相同代码的情况,对于线程执行不同代码的情况,处理方式比较灵活,这里主要介绍...
  • 线程之间的数据共享

    万次阅读 2018-08-03 22:32:48
    线程之间的数据共享问题可以分为两类,一类是执行代码一直的的线程共享线程共享,另一类是执行代码不一致的线程共享问题。接下来分别进行总结。 一、执行代码一致的线程共享问题 如果每个线程执行的代码执行的代码...
  • JAVA 并发编程-线程之间共享数据(六)

    万次阅读 热门讨论 2015-07-25 10:09:05
    多线程共享数据的方式: 1,如果每个线程执行的代码相同,可以使用同一个Runnable对象,这个Runnable对象中有那个共享数据,例如,卖票系统就可以这么做。2,如果每个线程执行的代码不同,这时候需要用不同的...
  • Qt线程共享数据主要有两种方式: 1)使用共享内存。即使用一个两个线程都能够共享的变量(如全局变量),这样两个线程都能够访问和修改该变量,从而达到共享数据的目的。 2)使用singal/slot机制,把数据从一个...
  • 多线程数据隔离与数据共享是个矛盾体,有些数据需要隔离,比如每个人的银行账户,有些需要共享比如买票的总火车票数量,这个问题导致了这篇文章的出现,抽象出了这两类问题。     二、数据隔离   ...
  • C++多线程学习---线程间的共享数据

    千次阅读 2016-11-21 15:02:21
    多线程间的共享数据如果不加以约束是有问题的。最简单的方法就是对数据结构采用某种保护机制,通俗的表达就是: 确保只有进行修改的线程才能看到不变量被破坏时的中间状态。从其他访问线程的角度来看,修改不是已经...
  • 本文全文以售票系统为例,简诉了java多线程共享数据的两种方式、线程同步。文章可能还有很多不足,请大家谅解,欢迎大佬提意见。 本文使用到的东西 java eclipse 2019-11 文章目录写在前面本文使用到的东西1....
  • 由于单进程爬虫的种种弊端,以及大量...在写的过程中,不可避免的需要以多线程甚至多进程运行程序。因此解决多线程间以及多进程间的同步和通信问题成为必须。由于进程拥有独立资源,因此多进程同步比多线程同步要更难
  • 在前面文章中我们已经通过ThreadLocal来实现线程级别的数据共享。那么如果子线程想访问父线程的数据该怎么做呢,InheritableThreadLocal可以帮助我们实现 1 InheritableThreadLocal的使用 测试代码 private ...
  • ThreadLocal如何实现多线程资源共享

    千次阅读 热门讨论 2014-08-28 16:10:44
     通过ThreadLocal存取的数据,总是与当前线程相关,也就是说,JVM 为每个运行的线程,绑定了私有的本地实例存取空间,从而为多线程环境常出现的并发访问问题提供了一种隔离机制。 二、原理    ...
  • 当无法确定自己需要开多少线程来运行程序时可以用以下命令查看用于确认自己当前机器开多少线程效率是最高的(仅仅作为参考): 直接用lambda函数方式进行线程调用: ...在多线程分区间进行vector计算时会出问...
  • vent对象实现了简单的线程通信机制,它提供了设置信号,清楚信号,等待等用于实现线程间的通信。  1 设置信号  使用Event的set()方法可以设置Event对象内部的信号标志为真。Event对象提供了isSet
  • Java多线程变量共享与隔离

    千次阅读 2021-11-12 11:38:42
    线程相关 线程的相关API Thread.currentThread().getName():获取当前线程的名字 start():1.启动当前线程2.调用线程中的run方法 run():通常需要重写Thread类中的此方法,将创建的线程要执行的操作声明在此方法中 ...
  • 1、运用多线程和Socket技术实现Socket Server端侦听多个客户端请求; 2、实现服务器端循环处理客户端不同请求从而实现不同测试要求,并向客户端循环发送数据; 3、实现客户端向服务器端发送不同测试命令,并接收...
  • 【java并发】线程共享数据

    万次阅读 多人点赞 2016-05-31 22:56:36
    先看一个多线程共享数据的问题: 设计四个线程,其中两个线程每次对data增加1,另外两个线程每次对data减少1。  从问题来看,很明显涉及到了线程间通数据共享,四个线程共享一个data,共同操作一个data。我们...
  • linux下线程间数据是否共享

    千次阅读 2018-10-28 17:49:49
    由打印结果得到,主线程中的数据被子线程修改,所以同一进程中不同线程数据共享。 2、 主线程将子线程写入文件的数据读出,所以同一进程的不同线程间的文件描述符是共享的。 3、 主线程中在堆区上开辟一段空间...
  • 二、如何实现线程间的数据共享多线程同步原理)1.为什么通过synchronized就能实现多线程间串行运行呢?①只能有一个线程位于临界区②临界区中的代码具有互斥性、唯一性和排它性:2.误区:“共享数据”是一个表达式...
  • 2.数据共享问题分析 2.1 只读数据 2.2 有读有写: 3.共享数据的保护案例代码 1.创建和等待线程 a)线程执行顺序是乱的,跟操作系统内部对线程的运行调度机制有关; b)主线程等待所有子线程运行结束,...
  • 多线程之不共享数据共享数据

    千次阅读 2017-03-30 09:14:55
    西城旧梦梦旧人 2017-03-28 18:00 ...不共享数据就是每个都是独立的线程,再去调自己的start方法就可以不共享数据了,下面看下代码。 public class NotShareData extends Thread { private int coun

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 571,777
精华内容 228,710
关键字:

多线程数据共享

友情链接: FFT.rar