2009-06-14 7 views
0

私はlock()、unlock()、query1()、query2()、query3()の各関数を持っています。クエリ関数はデータベース上でいくつかのクエリを実行するだけで、それに対するr/wアクセスと考えることができます。彼らはロックしていません。私のシステムはマルチスレッド化されています。データベーストランザクションとスレッド

スレッドp1からlock()が呼び出された場合、スレッドp1からのクエリのみが実行され、他のすべてのスレッドからのクエリはロック解除を待機します。これはどうすればいいですか?

私はpthreadsをCから使用しています。これを行うには、スレッドはロックを保持していることを知っている必要があります。しかし、pthreadsはそのような機能を持っていません。

デザインが間違っていますか?

編集:私は(ロックで欲しい

Function1(){ 
lock(); 
query1(); 
query2(); 
doQuery3(); 
unlock(); 
} 

doQuery3(){ 
lock(); 
query3(); 
unlock(); 
} 

行動)は、スレッドが既にロックを保持している場合、それはロックを待つべきではないということです。それはただ実行する必要があります。事は私のlock()関数が実際にトランザクションを開始することです。私はトランザクションでたくさんのものを実行したい。 unlock()はトランザクションを終了します。私はクエリを連鎖できるようにしたい。回避策の1つは、doQuery3()の代わりにFunction1()でquery3()を呼び出すことです。これは、すべての関数に2つのバージョンがあり、1つはロックと1つのバニラクエリを持つことを意味します。

これらのロックとロック解除の機能は、ミューテックスロックであっても、そうでなくてもかまいません。私はpthread mutexで実装しようとしましたが、できませんでした。同じスレッド上のpthread_mutex_lockがブロックするため!クールなトリック?

+0

これをよりうまく実装する方法については、さらに詳しい情報が必要です。このロック戦略で何を達成しようとしていますか? – Schwern

+0

私はあなたがPTHREAD_MUTEX_RECURSIVEをして、スレッドが同じロックを2回以上取得できるようにしたいと思う。 – ChrisW

答えて

1

...

私が欲しい機能は次のとおりです。ロックが()スレッドP1から呼び出された場合、唯一のスレッドP1からのクエリがします実行し、他のすべてのスレッドからの照会はロック解除を待ちます。これはどうすればいいですか?

P1のスレッドによって呼び出された作業単位がこのようであれば...

void doQuery1() 
{ 
    //get the lock 
    //if someone else has the lock, block until it's released 
    lock(); 

    //now we have the lock 
    //do query 
    query1(); 

    //our work is done 
    //release the lock, let another thread run 
    unlock(); 
} 

...とのスレッドが似ている他の人によって呼び出さ仕事...

void doQuery2() 
{ 
    lock(); 
    query2(); 
    unlock(); 
} 

void doQuery3() 
{ 
    lock(); 
    query3(); 
    unlock(); 
} 

... p1にロックがある場合、他のスレッドもクエリを試みる前にロック機能を呼び出すため、ロック機能がロック解除を待つため、あなたの質問に対する答えと思います。他のスレッドからのクエリwiロックが解除されるのを待ちます(つまり、すべてのスレッドが常にロックを呼び出し、ロックがロック解除を待つため)。

+0

再帰的なミューテックスが私に機能を与えました。 :D – jetru

2

はい、デザインが間違っています。

データベースでロックが行われている必要があります。私はしかし、あなたの質問/デザインを理解してきたかわからない

+1

私は同意します。これは現代のデータベースが扱えるように作られたものです。あなたは、データベース、テーブルまたは行レベルでロックすることができます。読み取りと書き込みのためにロックすることができます。一般的にトランザクションを使用する方がロックより優れていますが、もっと情報がなければもっと言い表せません。 – Schwern

0

さて、あなたはロックとロック解除の実装を見ているようですね?ここでは、クリティカルセクションを達成する方法の概要を示します。あなたの機能を実装するためにこれを使用することができますが、:

pthread_mutex_t mutex; 
pthread_mutex_init(&mutex, NULL); 
pthread_mutex_lock(&mutex); 
queryN(); // critical section 
pthread_mutex_unlock(&mutex); 

データベースが唯一のあなたの単一のプログラムからアクセスされた場合、それはあなたのために動作します。私はあなたのクエリがr/wをしていると思う、あなたのデータベースは、テーブル/行のいずれかの場合に応じて、適切なロックを行っていると思う。

すべてのクエリがロックとロック解除に囲まれている場合、あなたは望みのものを達成できます。

0
  • データベースでロックが処理されている場合。 SQLデータベースの場合、トランザクションは明示的に開始されるか、最初のSQL文で開始され、コミット作業が終了します。共有データを使用している場合は、プログラムを同期させるだけで済みます(キューを使用しているなど)。

  • データベースがロックを処理していない場合は、ロックは次のように使用する必要があります。

    START_TRANSACTION = pthread_mutex_lock

    END_TRANSACTION = pthread_mutex_unlock

が、何のロールバック処理や無矛盾に対する保護はありません。

関連する問題