使用named_mutex實現讀寫鎖,實現進程之間讀共享寫獨占

代碼

  • 代碼的名稱是read_write_mutex.h
  • 這個代碼可用,但是未優化,還存在冗余的代碼
  • 如果涉及到進程掛掉了,造成進程堵塞,如何解決?還未涉及
//#ifndef BOOST_THREAD_PTHREAD_SHARED_MUTEX_HPP
#define BOOST_THREAD_PTHREAD_SHARED_MUTEX_HPP//  (C) Copyright 2006-8 Anthony Williams
//  (C) Copyright 2012 Vicente J. Botet Escriba
//
//  Distributed under the Boost Software License, Version 1.0. (See
//  accompanying file LICENSE_1_0.txt or copy at
//  http://www.boost.org/LICENSE_1_0.txt)#include <boost/assert.hpp>
#include <boost/static_assert.hpp>
#include <boost/thread/mutex.hpp>
#include <boost/thread/condition_variable.hpp>
#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
#include <boost/thread/detail/thread_interruption.hpp>
#endif
#ifdef BOOST_THREAD_USES_CHRONO
#include <boost/chrono/system_clocks.hpp>
#include <boost/chrono/ceil.hpp>
#endif
#include <boost/thread/detail/delete.hpp>
#include <boost/assert.hpp>#include <boost/config/abi_prefix.hpp>
#include <boost/interprocess/sync/named_mutex.hpp>
#include <boost/interprocess/sync/named_condition.hpp>namespace bip = boost::interprocess;
namespace chy
{class shared_mutex{private:class state_data{public:state_data () :shared_count(0),exclusive(false),upgrade(false),exclusive_waiting_blocked(false){}void assert_free() const{BOOST_ASSERT( ! exclusive );BOOST_ASSERT( ! upgrade );BOOST_ASSERT( shared_count==0 );}void assert_locked() const{BOOST_ASSERT( exclusive );BOOST_ASSERT( shared_count==0 );BOOST_ASSERT( ! upgrade );}void assert_lock_shared () const{BOOST_ASSERT( ! exclusive );BOOST_ASSERT( shared_count>0 );//BOOST_ASSERT( (! upgrade) || (shared_count>1));// if upgraded there are at least 2 threads sharing the mutex,// except when unlock_upgrade_and_lock has decreased the number of readers but has not taken yet exclusive ownership.}void assert_lock_upgraded () const{BOOST_ASSERT( ! exclusive );BOOST_ASSERT(  upgrade );BOOST_ASSERT(  shared_count>0 );}void assert_lock_not_upgraded () const{BOOST_ASSERT(  ! upgrade );}bool can_lock () const{return ! (shared_count || exclusive);}void exclusive_blocked (bool blocked){exclusive_waiting_blocked = blocked;}void lock (){exclusive = true;}void unlock (){exclusive = false;exclusive_waiting_blocked = false;}bool can_lock_shared () const{return ! (exclusive || exclusive_waiting_blocked);}bool more_shared () const{return shared_count > 0 ;}unsigned get_shared_count () const{return shared_count ;}unsigned  lock_shared (){return ++shared_count;}void unlock_shared (){--shared_count;}bool unlock_shared_downgrades(){if (upgrade) {upgrade=false;exclusive=true;return true;} else {exclusive_waiting_blocked=false;return false;}}void lock_upgrade (){++shared_count;upgrade=true;}bool can_lock_upgrade () const{return ! (exclusive || exclusive_waiting_blocked || upgrade);}void unlock_upgrade (){upgrade=false;--shared_count;}//private:unsigned shared_count;bool exclusive;bool upgrade;bool exclusive_waiting_blocked;};state_data state;
//        boost::mutex state_change;bip::named_mutex state_change{bip::open_or_create,"mutex"};
//        boost::condition_variable shared_cond;bip::named_condition shared_cond{bip::open_or_create,"read"};
//        boost::condition_variable exclusive_cond;bip::named_condition exclusive_cond{bip::open_or_create,"write"};boost::condition_variable upgrade_cond;void release_waiters(){exclusive_cond.notify_one();shared_cond.notify_all();}public:BOOST_THREAD_NO_COPYABLE(shared_mutex)shared_mutex(){}~shared_mutex(){}void lock_shared(){
#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONSboost::this_thread::disable_interruption do_not_disturb;
#endif
//            boost::unique_lock<boost::mutex> lk(state_change);
//            boost::unique_lock<bip::named_mutex>lk(state_change);boost::unique_lock<bip::named_mutex> lk(state_change);while(!state.can_lock_shared()){shared_cond.wait(lk);}state.lock_shared();}bool try_lock_shared(){
//            boost::unique_lock<boost::mutex> lk(state_change);boost::unique_lock<bip::named_mutex>lk(state_change);if(!state.can_lock_shared()){return false;}state.lock_shared();return true;}//#if defined BOOST_THREAD_USES_DATETIME
//        bool timed_lock_shared(boost::system_time const& timeout)
//        {
//#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
//            boost::this_thread::disable_interruption do_not_disturb;
//#endifboost::unique_lock<boost::mutex> lk(state_change);
//            boost::unique_lock<bip::named_mutex>lk(state_change);
//
//            while(!state.can_lock_shared())
//            {
//                if(!shared_cond.timed_wait(lk,timeout))
//                {
//                    return false;
//                }
//            }
//            state.lock_shared();
//            return true;
//        }//        template<typename TimeDuration>
//        bool timed_lock_shared(TimeDuration const & relative_time)
//        {
//            return timed_lock_shared(boost::get_system_time()+relative_time);
//        }
//#endif
#ifdef BOOST_THREAD_USES_CHRONOtemplate <class Rep, class Period>bool try_lock_shared_for(const boost::chrono::duration<Rep, Period>& rel_time){return try_lock_shared_until(boost::chrono::steady_clock::now() + rel_time);}template <class Clock, class Duration>bool try_lock_shared_until(const boost::chrono::time_point<Clock, Duration>& abs_time){
#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONSboost::this_thread::disable_interruption do_not_disturb;
#endif
//          boost::unique_lock<boost::mutex> lk(state_change);boost::unique_lock<bip::named_mutex>lk(state_change);while(!state.can_lock_shared())//while(state.exclusive || state.exclusive_waiting_blocked){
//              if(boost::cv_status::timeout==shared_cond.wait_until(lk,abs_time))
//              {
//                  return false;
//              }}state.lock_shared();return true;}
#endifvoid unlock_shared(){
//            boost::unique_lock<boost::mutex> lk(state_change);boost::unique_lock<bip::named_mutex>lk(state_change);state.assert_lock_shared();state.unlock_shared();if (! state.more_shared()){if (state.upgrade){// As there is a thread doing a unlock_upgrade_and_lock that is waiting for ! state.more_shared()// avoid other threads to lock, lock_upgrade or lock_shared, so only this thread is notified.state.upgrade=false;state.exclusive=true;//lk.unlock();upgrade_cond.notify_one();}else{state.exclusive_waiting_blocked=false;//lk.unlock();}release_waiters();}}void lock(){
#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONSboost::this_thread::disable_interruption do_not_disturb;
#endif
//            boost::unique_lock<boost::mutex> lk(state_change);boost::unique_lock<bip::named_mutex>lk(state_change);while (state.shared_count || state.exclusive){state.exclusive_waiting_blocked=true;exclusive_cond.wait(lk);}state.exclusive=true;}#if defined BOOST_THREAD_USES_DATETIMEbool timed_lock(boost::system_time const& timeout){
#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONSboost::this_thread::disable_interruption do_not_disturb;
#endif
//            boost::unique_lock<boost::mutex> lk(state_change);boost::unique_lock<bip::named_mutex>lk(state_change);while(state.shared_count || state.exclusive){state.exclusive_waiting_blocked=true;if(!exclusive_cond.timed_wait(lk,timeout)){if(state.shared_count || state.exclusive){state.exclusive_waiting_blocked=false;release_waiters();return false;}break;}}state.exclusive=true;return true;}template<typename TimeDuration>bool timed_lock(TimeDuration const & relative_time){return timed_lock(boost::get_system_time()+relative_time);}
#endif
#ifdef BOOST_THREAD_USES_CHRONOtemplate <class Rep, class Period>bool try_lock_for(const boost::chrono::duration<Rep, Period>& rel_time){return try_lock_until(boost::chrono::steady_clock::now() + rel_time);}template <class Clock, class Duration>bool try_lock_until(const boost::chrono::time_point<Clock, Duration>& abs_time){
#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONSboost::this_thread::disable_interruption do_not_disturb;
#endif
//          boost::unique_lock<boost::mutex> lk(state_change);boost::unique_lock<bip::named_mutex>lk(state_change);while(state.shared_count || state.exclusive){state.exclusive_waiting_blocked=true;
//              if(boost::cv_status::timeout == exclusive_cond.wait_until(lk,abs_time))
//              {
//                  if(state.shared_count || state.exclusive)
//                  {
//                      state.exclusive_waiting_blocked=false;
//                      release_waiters();
//                      return false;
//                  }
//                  break;
//              }}state.exclusive=true;return true;}
#endifbool try_lock(){
//            boost::unique_lock<boost::mutex> lk(state_change);boost::unique_lock<bip::named_mutex>lk(state_change);if(state.shared_count || state.exclusive){return false;}else{state.exclusive=true;return true;}}void unlock(){
//            boost::unique_lock<boost::mutex> lk(state_change);boost::unique_lock<bip::named_mutex>lk(state_change);state.assert_locked();state.exclusive=false;state.exclusive_waiting_blocked=false;state.assert_free();release_waiters();}void lock_upgrade(){
#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONSboost::this_thread::disable_interruption do_not_disturb;
#endif
//            boost::unique_lock<boost::mutex> lk(state_change);boost::unique_lock<bip::named_mutex>lk(state_change);while(state.exclusive || state.exclusive_waiting_blocked || state.upgrade){shared_cond.wait(lk);}state.lock_shared();state.upgrade=true;}#if defined BOOST_THREAD_USES_DATETIMEbool timed_lock_upgrade(boost::system_time const& timeout){
#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONSboost::this_thread::disable_interruption do_not_disturb;
#endif
//            boost::unique_lock<boost::mutex> lk(state_change);boost::unique_lock<bip::named_mutex>lk(state_change);while(state.exclusive || state.exclusive_waiting_blocked || state.upgrade){if(!shared_cond.timed_wait(lk,timeout)){if(state.exclusive || state.exclusive_waiting_blocked || state.upgrade){return false;}break;}}state.lock_shared();state.upgrade=true;return true;}template<typename TimeDuration>bool timed_lock_upgrade(TimeDuration const & relative_time){return timed_lock_upgrade(boost::get_system_time()+relative_time);}
#endif
#ifdef BOOST_THREAD_USES_CHRONOtemplate <class Rep, class Period>bool try_lock_upgrade_for(const boost::chrono::duration<Rep, Period>& rel_time){return try_lock_upgrade_until(boost::chrono::steady_clock::now() + rel_time);}template <class Clock, class Duration>bool try_lock_upgrade_until(const boost::chrono::time_point<Clock, Duration>& abs_time){
#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONSboost::this_thread::disable_interruption do_not_disturb;
#endif
//          boost::unique_lock<boost::mutex> lk(state_change);boost::unique_lock<bip::named_mutex>lk(state_change);while(state.exclusive || state.exclusive_waiting_blocked || state.upgrade){
//              if(boost::cv_status::timeout == shared_cond.wait_until(lk,abs_time))
//              {
//                  if(state.exclusive || state.exclusive_waiting_blocked || state.upgrade)
//                  {
//                      return false;
//                  }
//                  break;
//              }}state.lock_shared();state.upgrade=true;return true;}
#endifbool try_lock_upgrade(){
//            boost::unique_lock<boost::mutex> lk(state_change);boost::unique_lock<bip::named_mutex>lk(state_change);if(state.exclusive || state.exclusive_waiting_blocked || state.upgrade){return false;}else{state.lock_shared();state.upgrade=true;state.assert_lock_upgraded();return true;}}void unlock_upgrade(){
//            boost::unique_lock<boost::mutex> lk(state_change);boost::unique_lock<bip::named_mutex>lk(state_change);//state.upgrade=false;state.unlock_upgrade();if(! state.more_shared() ){state.exclusive_waiting_blocked=false;release_waiters();} else {shared_cond.notify_all();}}// Upgrade <-> Exclusivevoid unlock_upgrade_and_lock(){
#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONSboost::this_thread::disable_interruption do_not_disturb;
#endif
//            boost::unique_lock<boost::mutex> lk(state_change);boost::unique_lock<bip::named_mutex>lk(state_change);state.assert_lock_upgraded();state.unlock_shared();
//            while (state.more_shared())
//            {
//                upgrade_cond.wait(lk);
//            }state.upgrade=false;state.exclusive=true;state.assert_locked();}void unlock_and_lock_upgrade(){
//            boost::unique_lock<boost::mutex> lk(state_change);boost::unique_lock<bip::named_mutex>lk(state_change);state.assert_locked();state.exclusive=false;state.upgrade=true;state.lock_shared();state.exclusive_waiting_blocked=false;state.assert_lock_upgraded();release_waiters();}bool try_unlock_upgrade_and_lock(){
//          boost::unique_lock<boost::mutex> lk(state_change);boost::unique_lock<bip::named_mutex>lk(state_change);state.assert_lock_upgraded();if(    !state.exclusive&& !state.exclusive_waiting_blocked&& state.upgrade&& state.shared_count==1){state.shared_count=0;state.exclusive=true;state.upgrade=false;state.assert_locked();return true;}return false;}
#ifdef BOOST_THREAD_USES_CHRONOtemplate <class Rep, class Period>booltry_unlock_upgrade_and_lock_for(const boost::chrono::duration<Rep, Period>& rel_time){return try_unlock_upgrade_and_lock_until(boost::chrono::steady_clock::now() + rel_time);}template <class Clock, class Duration>booltry_unlock_upgrade_and_lock_until(const boost::chrono::time_point<Clock, Duration>& abs_time){
#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONSboost::this_thread::disable_interruption do_not_disturb;
#endif
//          boost::unique_lock<boost::mutex> lk(state_change);boost::unique_lock<bip::named_mutex>lk(state_change);state.assert_lock_upgraded();if (state.shared_count != 1){
//              for (;;)
//              {
//                  boost::cv_status status = shared_cond.wait_until(lk,abs_time);
//                if (state.shared_count == 1)
//                  break;
//                if(status == boost::cv_status::timeout)
//                  return false;
//              }}state.upgrade=false;state.exclusive=true;state.exclusive_waiting_blocked=false;state.shared_count=0;return true;}
#endif// Shared <-> Exclusivevoid unlock_and_lock_shared(){
//            boost::unique_lock<boost::mutex> lk(state_change);boost::unique_lock<bip::named_mutex>lk(state_change);state.assert_locked();state.exclusive=false;state.lock_shared();state.exclusive_waiting_blocked=false;release_waiters();}#ifdef BOOST_THREAD_PROVIDES_SHARED_MUTEX_UPWARDS_CONVERSIONSbool try_unlock_shared_and_lock(){boost::unique_lock<boost::mutex> lk(state_change);state.assert_lock_shared();if(    !state.exclusive&& !state.exclusive_waiting_blocked&& !state.upgrade&& state.shared_count==1){state.shared_count=0;state.exclusive=true;return true;}return false;}
#ifdef BOOST_THREAD_USES_CHRONOtemplate <class Rep, class Period>booltry_unlock_shared_and_lock_for(const chrono::duration<Rep, Period>& rel_time){return try_unlock_shared_and_lock_until(chrono::steady_clock::now() + rel_time);}template <class Clock, class Duration>booltry_unlock_shared_and_lock_until(const chrono::time_point<Clock, Duration>& abs_time){
#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONSboost::this_thread::disable_interruption do_not_disturb;
#endifboost::unique_lock<boost::mutex> lk(state_change);state.assert_lock_shared();if (state.shared_count != 1){for (;;){cv_status status = shared_cond.wait_until(lk,abs_time);if (state.shared_count == 1)break;if(status == cv_status::timeout)return false;}}state.upgrade=false;state.exclusive=true;state.exclusive_waiting_blocked=false;state.shared_count=0;return true;}
#endif
#endif// Shared <-> Upgradevoid unlock_upgrade_and_lock_shared(){
//            boost::unique_lock<boost::mutex> lk(state_change);boost::unique_lock<bip::named_mutex>lk(state_change);state.assert_lock_upgraded();state.upgrade=false;state.exclusive_waiting_blocked=false;release_waiters();}#ifdef BOOST_THREAD_PROVIDES_SHARED_MUTEX_UPWARDS_CONVERSIONSbool try_unlock_shared_and_lock_upgrade(){boost::unique_lock<boost::mutex> lk(state_change);state.assert_lock_shared();if(    !state.exclusive&& !state.exclusive_waiting_blocked&& !state.upgrade){state.upgrade=true;return true;}return false;}
#ifdef BOOST_THREAD_USES_CHRONOtemplate <class Rep, class Period>booltry_unlock_shared_and_lock_upgrade_for(const chrono::duration<Rep, Period>& rel_time){return try_unlock_shared_and_lock_upgrade_until(chrono::steady_clock::now() + rel_time);}template <class Clock, class Duration>booltry_unlock_shared_and_lock_upgrade_until(const chrono::time_point<Clock, Duration>& abs_time){
#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONSboost::this_thread::disable_interruption do_not_disturb;
#endifboost::unique_lock<boost::mutex> lk(state_change);state.assert_lock_shared();if(    state.exclusive|| state.exclusive_waiting_blocked|| state.upgrade){for (;;){cv_status status = exclusive_cond.wait_until(lk,abs_time);if(    ! state.exclusive&& ! state.exclusive_waiting_blocked&& ! state.upgrade)break;if(status == cv_status::timeout)return false;}}state.upgrade=true;return true;}
#endif
#endif};typedef shared_mutex upgrade_mutex;
}#include <boost/config/abi_suffix.hpp>//#endif

測試代碼

#include <boost/thread/thread.hpp>
#include <boost/interprocess/sync/scoped_lock.hpp>
#include <boost/interprocess/sync/named_mutex.hpp>
#include <boost/ref.hpp>#include "read_write_mutex.h"#include <string>
#include <mutex>chy::shared_mutex global_mutex;
int global_num = 10;//全局變量,寫者改變全局變量,讀者讀全局變量
namespace bip = boost::interprocess;
//bip::named_mutex global_mutex(bip::open_or_create,"mtx");//讀線程
void read_thread(std::string &name){
//    boost::lock_guard<bip::named_mutex> lock(global_mutex);//讀鎖定
//    bip::named_mutex global_mutex(bip::open_or_create,"mtx");
//    global_mutex.lock();boost::shared_lock<chy::shared_mutex> lock{global_mutex};printf("線程%s搶占了資源,global_num = %d\n",name.c_str(),global_num);boost::this_thread::sleep(boost::posix_time::seconds(1));printf("線程%s釋放了資源...\n",name.c_str());
//    global_mutex.unlock();
}//寫線程
void write_thread(std::string &name){
//    std::lock_guard<bip::named_mutex> lock(global_mutex);//寫鎖定
//    bip::named_mutex global_mutex(bip::open_or_create,"mtx");
//    global_mutex.lock();boost::lock_guard<chy::shared_mutex> lock{global_mutex};global_num++;//寫線程改變數據的數值printf("線程%s搶占了資源,global_num = %d\n",name.c_str(),global_num);boost::this_thread::sleep(boost::posix_time::seconds(1));printf("線程%s釋放了資源...\n",name.c_str());
//    global_mutex.unlock();
}int main(){std::string read_thread_r1 = "read_thread_r1";std::string read_thread_r2 = "read_thread_r2";std::string read_thread_r3 = "read_thread_r3";std::string read_thread_r4 = "read_thread_r4";std::string read_thread_r5 = "read_thread_r5";std::string write_thread_w1 = "write_thread_w1";std::string write_thread_w2 = "write_thread_w2";boost::thread_group tg;tg.create_thread(boost::bind(read_thread,boost::ref(read_thread_r1)));tg.create_thread(boost::bind(read_thread,boost::ref(read_thread_r2)));tg.create_thread(boost::bind(read_thread,boost::ref(read_thread_r3)));tg.create_thread(boost::bind(read_thread,boost::ref(read_thread_r4)));tg.create_thread(boost::bind(read_thread,boost::ref(read_thread_r5)));tg.create_thread(boost::bind(write_thread,boost::ref(write_thread_w1)));tg.create_thread(boost::bind(write_thread,boost::ref(write_thread_w2)));tg.join_all();return 0;
}

?

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/446820.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/446820.shtml
英文地址,請注明出處:http://en.pswp.cn/news/446820.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Android Activity之間傳遞類對象

一、簡介 開發過程中&#xff0c;Activity之間傳遞數據是必不可少的&#xff0c;Android中使用Intent和Bundle作為數據載體&#xff0c;在Activity之間傳遞&#xff0c;對于基礎數據類型&#xff0c;Bundle已經提供了相關的put、set方法&#xff0c;而作為自定義的類型則需要有…

C++3個漢諾塔遞歸問題

3個漢諾塔問題A—>C 移動次數2^n-1 hannoni(int n,char a,char b,char c)把n個盤子借助b,從a移動到cmove(int n,char a,char c)把第n個盤子,從a移動到c #include<iostream> #include<cmath> using namespace std; //漢諾塔問題A--->C //2^n-1次移動次數 …

clion編譯器解決undefined reference to symbol ‘shm_open@@GLIBC_2.2.5‘

修改CMakelists文件 cmake_minimum_required(VERSION 3.17) project(mutex_learn)set(CMAKE_CXX_STANDARD 14)set(BOOST_ROOT "/usr/local/include/boost") #添加頭文件搜索路徑 include_directories(/usr/local/include) #添加庫文件搜索路徑 link_directories(/us…

Android 攔截或屏蔽返回鍵

在Android開發中我們常常會遇到需要攔截或屏蔽返回鍵的需求&#xff0c;對攔截后的返回鍵進行特殊操作。 監聽返回鍵有兩種方式 1、重寫OnBackPressed方法 Overridepublic void onBackPressed() {// 完全由自己控制返回鍵邏輯&#xff0c;系統不再控制&#xff0c;但是有個前…

C++遞歸斐波那契數列

第一種 //斐波那契數列 // 0 1 1 … //從第1個開始 代碼 #include<iostream> #include<cmath> using namespace std; //斐波那契數列 // 0 1 1 ... //從第1個開始 int f(int n) {int m; if(n1)return 0;if(n2)return 1;elsemf(n-1)f(n-2);return m;} int mai…

Android onActivityResult中requestCode與resultCode區別

想要了解requestCode與resultCode的區別&#xff0c;我們需要先了解以下三個方法的用法&#xff1a; startActivityForResult(Intent intent, Int requestCode) setResut(int resultCode, Intent intent) onActivityResult(int requestCode, int resultCode, Intent intent) …

使用named_mutex和named_condition配合實現讀寫鎖

代碼 代碼的名稱是read_write_mutex.h初步優化如果涉及到進程掛掉了&#xff0c;造成進程堵塞&#xff0c;如何解決&#xff1f;還未涉及 #include <boost/interprocess/sync/named_condition.hpp> #include <boost/interprocess/sync/named_mutex.hpp>namespace …

C++的輸入與輸出

輸入與輸出 輸入:從外部輸入設備(鍵盤)向計算機輸入數據 輸出:從計算機向外部輸出設備(顯示屏)輸出數據 C使用流對象實現 使用流對象cin與cout,將標準輸入輸出流庫的頭文件iostream包含到源文件 #include<iostream>//標準輸入輸出庫 using namespace std;//使用標準命…

Android 動態計算ListView的高度

目錄一、簡介二、效果圖三、代碼實現一、簡介 在Android開發的過程中有的時候我們需要手動計算ListView的高度&#xff0c;比如說&#xff0c;ScrollView中嵌套ListView的時候&#xff0c;我們就需要手動精確計算ListView的高度了。 如果ListView的Item高度是固定的話還好計算…

DjangoRestFramework(drf實現五個接口)

安裝&#xff1a;pip install djangorestframework 在使用drf之前&#xff0c;先 使用原生Django實現5個接口 models.py from django.db import modelsclass Book(models.Model):namemodels.CharField(max_length53)pricemodels.IntegerField() views.py from app01 impor…

linux使用共享內存進行進程通信

一、什么是共享內存 共享內存就是允許兩個不相關的進程訪問同一個邏輯內存。共享內存是在兩個正在運行的進程之間共享和傳遞數據的一種非常有效的方式。不同進程之間共享的內存通常為同一段物理內存。使用共享內存進行通信的進程都需要同一段共享內存連接到它們自己的地址空間…

安卓TextView文本框與自定義邊框

常用屬性 自定義邊框 基本使用 <?xml version"1.0" encoding"utf-8"?> <shape xmlns:android"http://schemas.android.com/apk/res/android"android:shape"rectangle矩形/ring圓環/oval橢圓/line直線"當為圓環時android:s…

Android RecyclerView實現九宮格效果

RecyclerView更加優化的復用機制和方便實現UI效果&#xff0c;幾乎替代Listview和GridView的使用。但是分割線的實現&#xff0c;需要自己繼承ItemDecoration來繪制。 完整代碼已上傳至Github&#xff1a;RecyclerView實現九宮格效果 效果圖 item的布局文件 <?xml versi…

如何讀取指針指向的地址空間呢?

方法 使用%p 接收指針返回的地址空間 代碼 #include <stdio.h> #include <stdlib.h>int main() {int a 100;int *a_p &a;printf("%p\n",&a);//輸出&#xff1a;002AF744 輸出的是a變量的地址printf("%p\n",a_p);//輸出&#xff1…

科學究研明表,漢字序順并不一定影閱響讀

有個很有意思的現象&#xff1a; 不信你就來試試 中文打亂小工具 github地址&#xff1a;在線打亂文字順序

安卓EditText

常用屬性 android:textAllCaps"false"去除大寫狀態 inputType 常用 textpassword密碼 number數字 phone撥號鍵盤 設置光標位置 editText.setSelection(2);從1開始 editText.setSelection(1,3);從1開始,1–3中間部分,一個范圍

完善博文 共享內存一寫多讀無鎖實現的代碼邏輯部分

使用共享內存(內存映射)實現發布訂閱模式 多進程實現PubSub發布訂閱模式&#xff0c;從而實現進程間的通信。通信方式可以是TCP/UDP&#xff0c;管道Pipe/消息隊列&#xff0c;共享內存shared memory等等。其中TCP/UDP的方式是可以用作局域網以及跨平臺的通信&#xff0c;Pipe…

想對你說的話,就在這里!

甜(Tu)言(Wei)蜜(Qing)語(Hua)最近在github上看到了一個朋友開發的 土味情話在線生成器 &#xff0c;感覺還不錯&#xff0c;在這里推薦一下。 github地址&#xff1a;在線生成土味情話

linux讀寫文件 簡單版

代碼 //write void write_file(const std::string file_name){FILE *fp nullptr;fp fopen(file_name.c_str(),"w");fprintf(fp,"This is testing for mutex\n");fclose(fp); } //read void read_file(const std::string file_name){std::ifstream fp(fi…

具有中國風的傳統顏色(炫酷)

一個小小的中國風的傳統顏色&#xff0c;你覺得應該是什么樣子的呢&#xff1f; 看了下面這個&#xff0c;我一個搞移動開發的都想去搞前端開發了。 廢話不多說了&#xff0c;直接看效果&#xff1a; 訪問地址&#xff1a;中國傳統顏色手冊 github地址&#xff1a;Chinese…