多进程用户并发处理Demo(C#版)

这个示例主要演示的是在多进程操作数据库时,如何避免并发重复数据入库的例子。

过多的线程理论不再阐述,网上、书上皆有。

项目采用 Asp.Net Framework 4.5 / Mysql 5.4 数据库。

首先创建一个 LockInsertDB.cs 文件,这个文件用来实现数据库添加;

1 using System;
 2 using MySql;
 3 using MySql.Data.MySqlClient;
 4 using System.Collections.Generic;
 5 using System.Linq;
 6 using System.Text;
 7 using System.Threading.Tasks;
 8 
 9 namespace DBImportTool
10 {
11     public class LockInsertDB : Common
12     {
13         private object obj = new object();
14         /// <summary>
15         /// 添加测试数据
16         /// </summary>
17         /// <param name="path">字段内容</param>
18         /// <param name="tname">线程名称</param>
19         public void InsertTestDB(string path, object tname)
20         {
21             MySql.Data.MySqlClient.MySqlConnection conn = new MySql.Data.MySqlClient.MySqlConnection("Server=10.17.1.57; Database=videodb; Uid=root; Pwd=xingzhi");
22             try
23             {
24                 conn.Open();//打开连接
25                 MySql.Data.MySqlClient.MySqlCommand cmd = new MySql.Data.MySqlClient.MySqlCommand();
26                 cmd.Connection = conn;
27                 //加入多线程,排它锁机制.
28                 lock (obj)
29                 {
30                     string select = "SELECT * FROM `tbl_test` WHERE `filepath` = ‘" + path + "‘";
31                     cmd.CommandText = select;
32                     object val = cmd.ExecuteScalar();
33                     if (val == null)
34                     {
35                         string sql = "INSERT INTO `tbl_test` (`filepath`, `addtime`) VALUES (‘" + path + "‘, NOW());";
36                         cmd.CommandText = sql;
37                         cmd.ExecuteNonQuery();
38                         P(DateTime.Now.ToString() + "\t" + tname + "\tOK\t" + path + "\n");
39                     }
40                     else
41                     {
42                         P(DateTime.Now.ToString() + "\t" + tname + "\t已存在\t" + path + "\n");
43                     }
44                 }
45             }
46             catch
47             {
48 
49             }
50             finally
51             {
52                 //关闭连接
53                 conn.Close();
54             }
55         }
56         /// <summary>
57         /// 测试输出
58         /// </summary>
59         /// <param name="str">输出内容字符串</param>
60         public void P(string str)
61         {
62             Console.Write(str);
63         }
64     }

65 }

再创建一个控制台工程,Main方法代码如下:

1 using System;
 2 using System.Threading;
 3 using System.IO;
 4 using System.Collections.Generic;
 5 using System.Linq;
 6 using System.Text;
 7 using System.Threading.Tasks;
 8 namespace DBImportTool
 9 {
10     public class Mcqueen
11     {
12         static void Main(string[] args)
13         {
14             Run();
15             Console.ReadLine();
16         }
17         /// <summary>
18         /// 进程数量.
19         /// </summary>
20         static int tnum = 2;
21         /// <summary>
22         /// 所对象
23         /// </summary>
24         static object obj = new object();
25         /// <summary>
26         /// 线程数组.
27         /// </summary>
28         static Thread[] threadarr = new Thread[tnum];
29         /// <summary>
30         /// 数据库插入对象.
31         /// </summary>
32         static LockInsertDB mdb = new LockInsertDB();
33         /// <summary>
34         /// 运行函数
35         /// </summary>
36         public static void Run()
37         {
38             for (int i = 0; i < tnum; i++)
39             {
40                 Thread t = new Thread(T1);
41                 threadarr[i] = t;
42                 threadarr[i].Name = "Thread " + i.ToString() + " :";
43             }
44             int y = 0;
45             while (y < tnum)
46             {
47                 threadarr[y].Start(threadarr[y].Name);
48                 y++;
49             }
50         }
51         /// <summary>
52         /// 读取磁盘文件路径.
53         /// </summary>
54         /// <param name="tname">线程名称</param>
55         public static void T1(object tname)
56         {
57             DirectoryInfo di = Directory.CreateDirectory(@"F:\邢智的文件\");
58             GetFiles(di, tname);
59         }
60         /// <summary>
61         /// 采用对列入栈模式对列遍历文件夹结构.
62         /// </summary>
63         /// <param name="di">目录对象</param>
64         /// <param name="tobj">线程名称</param>
65         private static void GetFiles(DirectoryInfo di,object tobj)
66         {
67             int sgin = 1;
68             Stack<DirectoryInfo> stack_dir = new Stack<DirectoryInfo>();
69             DirectoryInfo dir = di;
70             stack_dir.Push(di);
71             while (stack_dir.Count != 0)
72             {
73                 dir = stack_dir.Pop();
74                 DirectoryInfo[] diarr = dir.GetDirectories();
75                 foreach (DirectoryInfo d in diarr)
76                     stack_dir.Push(d);
77                 FileInfo[] files = dir.GetFiles();
78                 foreach (FileInfo f in files)
79                 {
80                     mdb.InsertTestDB(f.FullName.Replace("\\", "\\\\"), tobj);
81                     Thread.Sleep(200);
82                     sgin++;
83                 }
84             }
85         }
86         public static void P(string str)
87         {
88             Console.Write(str);
89         }
90     }

91 }

static LockInsertDB mdb = new LockInsertDB();

一开始把这句初始化对象放到了private static void GetFiles(DirectoryInfo di,object tobj) 函数里面,虽然在后续的执行过程中没有任何问题,

但是初始化运行线程时导致了进程并发进入lock锁中,后来研究一下原因,是因为每个进程都在实例化化它的时候都会在lock中分配一个标识符,

这样一来,假如A进程内实例化了A1,那么当B进程进来之后,B却不认识A线程内的A1,因此lock也就对A1不起作用了。

因此把这个类跳出线程而放到一个全局中去实例化,也就不存在这个lock失效的问题了。

运行结果如下:

如果需要模拟更多的进程用户,只需要把 tnum = 2 的数值改一下即可。

时间: 2024-10-22 07:07:00

多进程用户并发处理Demo(C#版)的相关文章

项目构建之maven篇:8.maven发布web工程及基于spring mvc,jetty实现的用户管理demo

web工程目录结构 pom/pom.xml <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd&qu

EasyUI+MVC+EF简单用户管理Demo(问题及解决)

原文:http://www.cnblogs.com/xishuai/p/3635192.html 写在前面 iframe-src EntityFramework版本 connectionStrings View.Action.页面跳转 EasyUI中DataGrid绑定 新增.修改和删除数据 效果图.完整示例Demo下载 后记 关于EasyUI了解差不多,就想结合MVC.EF做一个简单的用户管理Demo,其实没多少东西,但这是小菜我第一次做.主要是熟悉下其中的流程,当然也遇到一些问题,走了很多的

vue入门:用户管理demo

该demo纯前端实现 使用到vue技术点: 1.在该demo中使用到的vue指令:{{}}. v-if. v-model. @click v-for 2.在该demo中使用到的事件修饰符: .prevent(阻止事件默认行为) 3.在该demo中使用到的api: arr.push(item,...):向数组末尾添加一个或多个元素 arr.splice(index,num) :删除并插入,删除指定索引和数量的元素,并添加新元素,参数1必须,参数2不给则清空数组,参数3不给则不添加新元素 arr.f

WordPress 前端投稿/编辑发表文章插件 DJD Site Post(支持游客和已注册用户)汉化版 免费下载

插件简介 前面逍遥乐给大家推荐了 WordPress用户前端化专业版WP User Frontend Pro WordPress中文汉化插件v2.1.9 今天逍遥乐给大家带来的wordpress插件是 WordPress 前端投稿/编辑插件 DJD Site Post,它不仅支持已注册用户投稿,还支持给匿名游客投稿,而且在投稿界面添加了登录链接,登录成功后自动返回投稿界面,体验很不错.该插件还允许用户上传媒体文件,集成WP自身的编辑器(可后台设置),支持选择分类和添加标签等等.支持有新文章投稿时

(一)Android OkHttp 用户登陆demo

android开发中网络通讯必不可少,目前使用率较高的http框架有Okhttp.nohttp.volley等等, 下面做一个用户登陆的demo,说明一下Okhttp的用法,废话不多说,看代码. LoginActivity.java 1 package com.junyi.shangqifixture; 2 3 import java.io.IOException; 4 5 import android.app.Activity; 6 import android.content.Intent;

用户登录(简易版)

#一.简易版用户登录,此程序直到用户输入正确的用户名和密码,不然不会退出 1 _name = "liangchen" 2 _passwd = "abc123" 3 while True: 4 username = input("username:") 5 password = input("password:") 6 if username == _name and password == _passwd: 7 print(&

PHP多进程学习(二)__来初步了解一下PHP多进程及简单demo

php是一门单进程弱类型的语言,PHP处理多并发主要是依赖服务器或PHP-FPM的多进程及它们进程的复用,多进程的作用优点大家可以去网上了解,PHP实现多进程在实际项目中意义也是不容小觑的.比如:日常任务中,有时需要通过php脚本执行一些日志分析,队列处理等任务,当数据量比较大时,可以使用多进程来处理. 要实现PHP的多进程,需要用到函数pcntl_fork,那么就需要开启扩展 pcntl和 posix,在上一篇文章已经有安装方法. 入门须知 孤儿进程:一个父进程退出,而它的一个或多个子进程还在

Linux用户管理命令(第二版)

添加用户 1.useradd -设置选项 用户名 [-D 查看缺省参数 ] 选项: u: UID [必须是系统中没有的] g:缺省所属用户组GID[最好有] G: 指定用户所属多个组[可以指定这个用户所属的部门等] d: 宿主目录[可以任意指定] s: 命令解释器Shell [必须是包含在/etc/shells文件中的] c:描述信息[可以用于描述该用户是谁,有什么权限,最好要有] e: 指定用户失效时间 E.g. useradd -u 6666 -g root -G sys,apache -d

项目构建之maven篇:8.maven公布webproject及基于spring mvc,jetty实现的用户管理demo

webproject文件夹结构 pom/pom.xml <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.