线程是任务调度的基本单位,一个进程中可以有多个线程,每个线程有自己的堆栈空间,

进程中的代码段、数据段和堆栈对进程中的线程是可见的。在使用线程时通常都要考虑数据的安全访问。

常用的线程同步方法有:

  • 互斥变量
  • 读写锁
  • 条件变量
  • 屏障
  • 自旋锁(用于CPU,锁住后CPU将不执行其他事情,即一直等待)

在OCCI程序中使能线程安全,则应指定THREADED_MUTEXED选项创建运行环境

例如:
Environment *env =
Environment::createEnvironment(Environment::THREADED_MUTEXED)

注意:

  • 如果应用程序是单线程,则使用默认值创建环境即可;

    如果指定THREADED_MUTEXED选项创建将会影响应用程序性能。
  • OCCI中的线程安全仅仅指的是EnvironmentMapConnectionPool

    StatelessConnectionPoolConnection对象。对于StatementResultSet

    SQLExceptionStream等不是线程安全的,因此不应该在多个线程中共享。

以下例子创建一个只有一个连接的无状态连接池,创建两个线程去竞争从池中得到连接

当以线程安全创建环境时程序运行正常,当使用默认选项创建环境时,程序将抛出异常:

what():  ORA-03117: two-task save area overflow
#include <iostream>
#include <cstdlib> #include <pthread.h>
#include <unistd.h>
#include <occi.h> #define USERNAME "scott"
#define PASSWORD "scott"
#define DBNAME "//192.168.42.135:1521/orcl"
#define MAXCON 1
#define MINCON 0
#define INCCON 1 using namespace oracle::occi;
using namespace std; void *displayAllRows(void *arg);
void *updateRow(void *arg); int main(void)
{
Environment *env = Environment::createEnvironment(Environment::THREADED_MUTEXED); //创建无状态连接池
StatelessConnectionPool *scp =
env->createStatelessConnectionPool(
USERNAME, PASSWORD, DBNAME, MAXCON, MINCON, INCCON,
StatelessConnectionPool::HOMOGENEOUS); //设置池中的连接空闲超时时间,超时后OCCI会自动释放此连接,需要时在创建
scp->setTimeOut(10); cout << "*****************Information**************************" << endl;
cout << "Open Connection : " << scp->getOpenConnections() << endl;
cout << "Busy Connection : " << scp->getBusyConnections() << endl;
cout << "Time Out Connection : " << scp->getTimeOut() << endl;
cout << "******************************************************" << endl; pthread_t tid_1, tid_2;
int err = 0;
err = pthread_create(&tid_1, NULL, displayAllRows, (void *)scp);
if (err != 0) {
cout << "create thread failure for tid_1." << endl;
} else {
cout << ">> create thread successful for tid_1." << endl;
} err = pthread_create(&tid_2, NULL, updateRow, (void *)scp);
if (err != 0) {
cout << "create thread failure for tid_2." << endl;
} else {
cout << ">> create thread successful for tid_2." << endl;
} pthread_join(tid_1, (void **)NULL);
pthread_join(tid_2, (void **)NULL); env->terminateStatelessConnectionPool(scp);
Environment::terminateEnvironment(env); return 0;
} void *displayAllRows(void *arg)
{
StatelessConnectionPool *scp = (StatelessConnectionPool *)arg; for ( ; ; )
{
std::cout << ">>>> displayAllRows thread runing [" << long(pthread_self()) << "]" << std::endl; Connection *conn = scp->getConnection(""); string sqlStmt = "SELECT * FROM DEPT WHERE DEPTNO=60"; Statement *stmt = conn->createStatement(sqlStmt); ResultSet *rset = stmt->executeQuery(); try {
while (rset->next()) {
cout << int(rset->getNumber(1)) << " ";
cout << rset->getString(2) << " ";
cout << rset->getString(3) << " ";
cout << endl;
}
}catch(SQLException &ex) {
cout << "display all rows failure." << endl;
cout << ex.getMessage();
cout << endl;
} sleep(5); stmt->closeResultSet(rset);
conn->terminateStatement(stmt);
scp->releaseConnection(conn, "");
} pthread_exit((void *)0);
} void *updateRow(void *arg)
{
StatelessConnectionPool *scp = (StatelessConnectionPool*)arg; for ( ; ; )
{
std::cout << ">>> updateRow thread running [" << long(pthread_self()) << "]" << std::endl; Connection *conn = scp->getConnection(""); string sqlStmt = "UPDATE DEPT SET LOC=:deptLocal WHERE DEPTNO=51"; Statement *stmt = conn->createStatement(sqlStmt); try {
stmt->setString(1, "ShangHai");
stmt->executeUpdate();
conn->commit();
} catch(SQLException &ex) {
cout << "update row failure." << endl;
cout << ex.getMessage();
cout << endl;
} conn->terminateStatement(stmt);
scp->releaseConnection(conn, ""); sleep(1);
} pthread_exit((void *)0);
}

OCCI线程安全的更多相关文章

  1. 转:c++ Oracle OCCI 编程

    原地址http://blog.sina.com.cn/s/blog_53a72add01015zj4.html 找不到具体的出处,只好不写了. OCCI数据库ORACLE编程步骤1. 配置环境(1)  ...

  2. oracle OCCI编程

    1. 创建OCCI环境变量 Environment *env = Environment::createEnvironment(); Environment对象的建立必须放在第一位,而且也必须是最后一 ...

  3. c++ Oracle OCCI 编程

    转载备忘:http://blog.sina.com.cn/s/blog_53a72add01015zj4.html 关于occi编程可以参考的链接: http://blog.itpub.net/162 ...

  4. [ 高并发]Java高并发编程系列第二篇--线程同步

    高并发,听起来高大上的一个词汇,在身处于互联网潮的社会大趋势下,高并发赋予了更多的传奇色彩.首先,我们可以看到很多招聘中,会提到有高并发项目者优先.高并发,意味着,你的前雇主,有很大的业务层面的需求, ...

  5. [高并发]Java高并发编程系列开山篇--线程实现

    Java是最早开始有并发的语言之一,再过去传统多任务的模式下,人们发现很难解决一些更为复杂的问题,这个时候我们就有了并发. 引用 多线程比多任务更加有挑战.多线程是在同一个程序内部并行执行,因此会对相 ...

  6. 多线程爬坑之路-学习多线程需要来了解哪些东西?(concurrent并发包的数据结构和线程池,Locks锁,Atomic原子类)

    前言:刚学习了一段机器学习,最近需要重构一个java项目,又赶过来看java.大多是线程代码,没办法,那时候总觉得多线程是个很难的部分很少用到,所以一直没下决定去啃,那些年留下的坑,总是得自己跳进去填 ...

  7. Java 线程

    线程:线程是进程的组成部分,一个进程可以拥有多个线程,而一个线程必须拥有一个父进程.线程可以拥有自己的堆栈,自己的程序计数器和自己的局部变量,但不能拥有系统资源.它与父进程的其他线程共享该进程的所有资 ...

  8. C++实现线程安全的单例模式

    在某些应用环境下面,一个类只允许有一个实例,这就是著名的单例模式.单例模式分为懒汉模式,跟饿汉模式两种. 首先给出饿汉模式的实现 template <class T> class sing ...

  9. 记一次tomcat线程创建异常调优:unable to create new native thread

    测试在进行一次性能测试的时候发现并发300个请求时出现了下面的异常: HTTP Status 500 - Handler processing failed; nested exception is ...

随机推荐

  1. 跟我一起用python画你所想吧!

    0.库的引入 要想画图,我们先倒入两个库. import numpy as np import matplotlib.pyplot as plt 注:以下代码全都基于导入这两个库的前提下编写的. 1. ...

  2. 模拟登陆并爬取Github

    因为崔前辈给出的代码运行有误,略作修改和简化了. 书上例题,不做介绍. import requests from lxml import etree class Login(object): def ...

  3. php 自带加密、解密函数

    php 自带的加密函数  不可逆的加密函数为:md5().crypt() md5() 用来计算 MD5 哈稀.语法为:string md5(string str); crypt() 将字符串用 UNI ...

  4. 导入的项目eclipse出现乱码的处理方法

    如果这样子还是出现乱码无法解决的话,则删掉当前项目重新开始项目.

  5. 移动Web开发与适配笔记

    项目要是适配手机端,想透彻的把相关内容弄清楚,现在总结一下. 一.移动端开发有如下特点: 1.跑在手机端的web 页面就是h5页面 2.具有跨平台性(web 安卓 iOS都适应) 3.基于webvie ...

  6. C#开发微信公众号.NET平台MVC微信开发Demo解决收不到消息的问题

    不得不说现在微信非常火,微信开放平台可以自己写程序跟用户交互,节省了前台开发成本,免去用户装客户端的烦恼.于是今天兴致来潮,想做一个试试. 首先找到了开发者文档,看了看,蛮简单的.(公众号早已申请,有 ...

  7. 【起航计划 003】2015 起航计划 Android APIDemo的魔鬼步伐 02 SimpleAdapter,ListActivity,PackageManager参考

    01 API Demos ApiDemos 详细介绍了Android平台主要的 API,android 5.0主要包括下图几个大类,涵盖了数百api示例:

  8. 当你的域名是数字开头时如何命名java包路径

    例如:域名是1001y.net 理想的包路径是net.1001y,但由于java命名规范的问题,首字母不能为数字,这时我们只有两种选择: 1,net.$1001y 使用$符号作为首字母. 2,net. ...

  9. django orm 多对多自定义第三张表

    # -*- coding: utf-8 -*-# Generated by Django 1.11.11 on 2018-09-02 08:07from __future__ import unico ...

  10. 自定义 sql Split函数 / 自定义mp_helptext查看存储

    1. 分割函数: --Split 表函数将一个字符串按指定分隔符进行分割,返回一个表. create function split( ),--待分割字符串 )--分割符 ))) as begin ) ...