__sync_fetch_and_add

2023-05-16

最近在公司离职的前辈写的代码哪里看到了__sync_fetch_and_add这个东东.比较好奇.找些资料学习学习

http://www.lxway.com/4091061956.htm

 http://www.cnblogs.com/FrankTan/archive/2010/12/11/1903377.html

可使用的环境: gcc.version > 4.1.2

作用:提供多线程下变量的加减和逻辑运算的原子操作

 正文如下:

最近编码需要实现多线程环境下的计数器操作,统计相关事件的次数。下面是一些学习心得和体会。不敢妄称原创,基本是学习笔记。遇到相关的引用,我会致谢。
    当然我们知道,count++这种操作不是原子的。一个自加操作,本质是分成三步的:
     1 从缓存取到寄存器
     2 在寄存器加1
     3 存入缓存。

mov eax,dword ptr [a]
add eax,1
mov dword ptr [a],eax


    由于时序的因素,多个线程操作同一个全局变量,会出现问题。这也是并发编程的难点。在目前多核条件下,这种困境会越来越彰显出来。
    最简单的处理办法就是加锁保护,这也是我最初的解决方案。看下面的代码:


1       pthread_mutex_t count_lock = PTHREAD_MUTEX_INITIALIZER;
2 
3       pthread_mutex_lock(&count_lock);
4       global_int++;
5       pthread_mutex_unlock(&count_lock);
linux 变量 : pthread_mutex_t
linux 函数 : pthread_mutex_lock; pthread_mutex_unlock

    后来在网上查找资料,找到了__sync_fetch_and_add系列的命令

     __sync_fetch_and_add系列一共有十二个函数,有加/减/与/或/异或/等函数的原子性操作函数,


__snyc_fetch_and_add : 先fetch然后自加,返回的是自加以前的值
__snyc_add_and_fetch : 先自加然后返回,返回的是自加以后的值 (参照 ++i 和 i++)


__snyc_fetch_and_add的一个简单使用
1
int count = 4; 2 __sync_fetch_and_add(&count, 1); // __sync_fetch_and_add(&count, 1) == 4 3 cout<<count<<endl; //--->count=5

    对于多线程对全局变量进行自加,我们就再也不用理线程锁了

下面这行代码,和上面被pthread_mutex保护的那行代码作用是一样的,而且也是线程安全的。


__sync_fetch_and_add( &global_int, 1 );  

    下面是这群函数的全家福,大家看名字就知道是这些函数是干啥的了。


 1 //在用gcc编译的时候要加上选项 -march=i686
 2 type __sync_fetch_and_add (type *ptr, type value, ...);
 3 type __sync_fetch_and_sub (type *ptr, type value, ...);
 4 type __sync_fetch_and_or (type *ptr, type value, ...);
 5 type __sync_fetch_and_and (type *ptr, type value, ...);
 6 type __sync_fetch_and_xor (type *ptr, type value, ...);
 7 type __sync_fetch_and_nand (type *ptr, type value, ...);
 8 type __sync_add_and_fetch (type *ptr, type value, ...);
 9 type __sync_sub_and_fetch (type *ptr, type value, ...);
10 type __sync_or_and_fetch (type *ptr, type value, ...);
11 type __sync_and_and_fetch (type *ptr, type value, ...);
12 type __sync_xor_and_fetch (type *ptr, type value, ...);
13 type __sync_nand_and_fetch (type *ptr, type value, ...);  

__sync_fetch_and_add,速度是线程锁的6~7倍

type可以是1,2,3或者8字节长度的int类型,即

 


 1 int8_t    
 2 uint8_t
 3 
 4 int16_t
 5 uint16_t
 6 
 7 int32_t
 8 uint32_t
 9 
10 int64_t
11 uint64_t  

 

后面的可扩展参数(...)用来指出哪些变量需要memory barrier,因为目前gcc实现的是full barrier(类似于linux kernel 中的mb(),表示这个操作之前的所有内存操作不会被重排序到这个操作之后),所以可以略掉这个参数。

 

恩.再找个帖子学习学习.http://blog.csdn.net/hzhsan/article/details/25124901

有一个概念叫过无锁化编程, 知道linux支持的哪些操作是具有原子特性的是理解和设计无锁化编程算法的基础

除了上面提到的12个外 还有4个可以实现互斥锁的功能


//以下两个函数提供原子的比较和交换, 如果*ptr = oldValue, 就将newValue写入*ptr
//第一个函数在相等并写入的情况下返回true
//第二个函数返回操作之前的值

bool __sync_bool_compare_and_swap(type* ptr, type oldValue, type newValue, ....);

type __sync_val_compare_and_swap(type* ptr, type oldValue, type newValue, ....);

//将*ptr设为value并返回*ptr操作之前的值
type __sync_lock_test_and_set(type *ptr, type value, ....);

//置*ptr为0
void __sync_lock_release(type* ptr, ....);  

 1 __sync_synchronize(...)
 2 
 3 //作用 : 发出一个full barrier
 4 /*关于memory barrier,cpu会对我们的指令进行排序,一般说来会提高程序的效率,但有时候可能造成我们不希望得到的结果,举一个例子,比如我们有一个硬件设备,它有4个寄存器,当你发出一个操作指令的时候,一个寄存器存的是你的操作指令(比如READ),两个寄存器存的是参数(比如是地址和size),最后一个寄存器是控制寄存器,在所有的参数都设置好之后向其发出指令,设备开始读取参数,执行命令,程序可能如下:*/
 5 write1(dev.register_size, size);
 6 write1(dev.register_addr, addr);
 7 write1(dev.register_cmd, Read);
 8 write1(dev.register_control, GO);
 9 /*如果最后一条write1被换到了前几条语句之前,那么肯定不是我们所期望的,这时候我们可以在最后一条语句之前加入一个memory barrier,强制cpu执行完前面的写入以后再执行最后一条:*/
10 write1(dev.register_size, size);
11 write1(dev.register_addr, addr);
12 write1(dev.register_cmd, Read);
13 __sync_synchronize();
14 write1(dev.register_control, GO);
15 
16 //memory barrier有几种类型:
17 //acquire barrier : 不允许将barrier之后的内存读取指令移到barrier之前(linux kernel中的wmb())
18 //release barrier : 不允许将barrier之前的内存读取指令移到barrier之后 (linux kernel中的rmb())
19 //full barrier    : 以上两种barrier的合集(linux kernel中的mb())
20 
21 //好吧,说实话这个函数的说明基本没看懂  

 

最后从网上找一个代码写一写:http://blog.csdn.net/hzhsan/article/details/25837189

测试场景:假设有一个应用:现在有一个全局变量,用来计数,再创建10个线程并发执行,每个线程中循环对这个全局变量进行++操作(i++),循环加2000000次。

所以很容易知道,这必然会涉及到并发互斥操作。下面通过三种方式[传统互斥量加锁方式, no lock不加锁的方式, 原子函数方式]来实现这种并发操作。并对比出其在效率上的不同之处。

这里先贴上代码,共5个文件:2个用于做时间统计的文件:timer.h  timer.cpp。这两个文件是临时封装的,只用来计时,可以不必细看。


 1 //timer.h 用于计时
 2 
 3 #ifndef TIMER_H_
 4 #define TIMER_H_
 5 
 6 #include <sys/time.h>
 7 
 8 class Timer
 9 {
10     public:
11         Timer();
12         Timer(const Timer& t) = delete;
13         ~Timer();
14 
15         void start();
16         void stop();
17         void reset();
18 
19         double costTime();
20 
21     private: 
22         struct timeval t1;
23         struct timeval t2;
24         bool b1, b2;
25 };  

//timer.cpp 
1
#include "timer.h" 2 #include <iostream> 3 4 using namespace std; 5 6 Timer::Timer():b1(false), b2(false) 7 { 8 } 9 Timer::~Timer() 10 { 11 } 12 void Timer::start() 13 { 14 gettimeofday(&t1, NULL); 15 b1 = true; 16 b2 = false; 17 } 18 void Timer::stop() 19 { 20 gettimeofday(&t2, NULL); 21 b2 = true; 22 } 23 void Timer::reset() 24 { 25 b1 = false; 26 b2 = false; 27 } 28 double Timer::costTime() 29 { 30 if (!b1) 31 { 32 cout<<"error, do not call function start()"<<endl; 33 cout<<"the right sequence : start() ..... stop() costTime()"<<endl; 34 35 return 0; 36 } 37 38 if (!b2) 39 { 40 cout<<"error, do not call function stop()"<<endl; 41 cout<<"the right sequence : start() ..... stop() costTime()"<<endl; 42 return 0; 43 } 44 45 size_t sec = t2.tv_sec - t1.tv_sec; 46 double usec = t2.tv_usec - t1.tv_usec; 47 48 if (sec < 0) 49 { 50 cout<<"error, call stop() before start()"<<endl; 51 cout<<"the right sequence : start() ..... stop() costTime()"<<endl; 52 return 0; 53 } 54 55 if (usec < 0) 56 { 57 usec += 1000000; 58 --sec; 59 if (sec < 0) 60 { 61 cout<<"error, call stop() before start()"<<endl; 62 cout<<"the right sequence : start() ..... stop() costTime()"<<endl; 63 return 0; 64 } 65 } 66 67 return sec + usec * 1.0 / 1000000; 68 }

 


1 //thread_function.h  -->多线程要调用的函数
2 #ifndef THREAD_FUNCTION_H_
3 #define THREAD_FUNCTION_H_
4 void* thread_lock_execFunc(void* arg);
5 void* thread_nolock_execFunc(void* arg);
6 void* thread_atom_execFunc(void* arg);
7 #endif  

 


 1 //thread_function.cpp
 2 #include "thread_function.h"
 3 #include "lock.h"
 4 #include <pthread.h>
 5 #include <unistd.h>
 6 
 7 extern volatile int count;
 8 struct LOCK;
 9 
10 void* thread_lock_execFunc(void* arg)
11 {
12 
13 
14     for (int i = 0; i < 2000000; ++i)
15     {
16         pthread_mutex_lock(reinterpret_cast<pthread_mutex_t*>(arg));
17         ++count;
18         pthread_mutex_unlock(reinterpret_cast<pthread_mutex_t*>(arg));
19     }
20 
21     return NULL;
22 }
23 
24 void* thread_nolock_execFunc(void* arg)
25 {
26     LOCK* pLock = reinterpret_cast<LOCK*>(arg);
27     for (int i = 0; i < 2000000; ++i)
28     {
29         while(!(__sync_bool_compare_and_swap(&(pLock->mutex), pLock->use, 1)))
30         {
31             usleep(100000);
32         }
33         ++count;
34         __sync_bool_compare_and_swap(&(pLock->mutex), pLock->unUse, 0);
35     }
36     return NULL;
37 }
38 
39 void* thread_atom_execFunc(void* arg)
40 {
41     for (int i = 0; i < 2000000; ++i)
42     {
43         __sync_fetch_and_add(&count, 1);
44     }
45 
46     return NULL;
47 }  

 


 1 //lock.h --->给mainnolock.cpp使用的类
 2 #ifndef LOCK_H_
 3 #define LOCK_H_
 4 struct LOCK
 5 {
 6     int mutex;
 7     int use;
 8     int unUse;
 9     LOCK() : mutex(0), use(0), unUse(1)
10     {
11     }
12 };
13 #endif  

 1 //mainlock.cpp  使用mutex加锁方式的多线程
 2 #include <iostream>
 3 #include <pthread.h>
 4 #include <iomanip>
 5 
 6 #include "timer.h"
 7 #include "thread_function.h"
 8 
 9 using namespace std;
10 
11 pthread_mutex_t mutex_lock;
12 volatile int count = 0;
13 
14 int main( int argc, char** argv)
15 {
16     pthread_mutex_init(&mutex_lock, NULL);
17 
18     Timer timer;
19     timer.start();
20     
21     /*test thread begin*/
22     pthread_t thread_ids[10];
23     
24     for (int i = 0; i < sizeof(thread_ids)/sizeof(pthread_t); ++i)
25     {
26         pthread_create(&thread_ids[i], NULL, thread_lock_execFunc, &mutex_lock);
27     }
28     
29     for (int i = 0; i < sizeof(thread_ids)/sizeof(pthread_t); ++i)
30     {
31         pthread_join(thread_ids[i], NULL);
32     }
33     /*test thread end*/
34 
35     timer.stop();
36     cout<<setiosflags(ios::fixed)<<setprecision(4)<<"lock cost["<<timer.costTime()<<"]second"<<endl;
37     return 0;
38 }  

 1 //main_nolock.cpp 使用__sync_compare_and_swap的多线程
 2 #include <iostream>
 3 #include <pthread.h>
 4 #include <unistd.h>
 5 #include <iomanip>
 6 #include "timer.h"
 7 #include "thread_function.h"
 8 #include "lock.h"
 9 
10 using namespace std;
11 
12 volatile int count = 0;
13 
14 int main(int argc, char** argv)
15 {
16     LOCK lock;
17 
18     Timer timer;
19     timer.start();
20 
21     /*test thread begin*/
22     pthread_t thread_ids[10];
23     for (int i = 0; i < sizeof(thread_ids) / sizeof(pthread_t); ++i)
24     {
25         pthread_create(&thread_ids[i], NULL, thread_nolock_execFunc, &lock);
26     }
27 
28     for (int i = 0; i < sizeof(thread_ids) / sizeof(pthread_t); ++i)
29     {
30         pthread_join(thread_ids[i], NULL);
31     }
32     /*test thread end*/
33     
34     timer.stop();
35     cout<<setiosflags(ios::fixed)<<setprecision(4)<<"nolock cost["<<timer.costTime()<<"]\n";    
36     return 0;
37 }  

 1 //main_atomic.cpp 使用__sync_fetch_and_add的多线程
 2 #include<iostream>
 3 #include<pthread.h>
 4 #include<unistd.h>
 5 #include<iomanip>
 6 #include "timer.h"
 7 #include "thread_function.h"
 8 
 9 using namespace std;
10 
11 volatile int count = 0;
12 
13 int main(int argc, char** argv)
14 {
15     Timer timer;
16     timer.start();
17 
18     /*pthread begin*/
19     pthread_t thread_ids[10];
20 
21     for (int i = 0; i < sizeof(thread_ids)/sizeof(pthread_t); ++i)
22     {
23         pthread_create(&thread_ids[i], NULL, thread_atom_execFunc, NULL);
24     }
25 
26     for (int i = 0; i < sizeof(thread_ids)/sizeof(pthread_t); ++i)
27     {
28         pthread_join(thread_ids[i], NULL);
29     }
30 
31     /*pthread end*/
32 
33     timer.stop();
34     cout<<setiosflags(ios::fixed)<<setprecision(4)<<"atomic cost["<<timer.costTime()<<"]\n";
35     return 0;
36 }  

 1 //makefile
 2 
 3 CC = g++
 4 CFLAGS = -g -lpthread -std=c++11
 5 
 6 OBJS_LOCK = main_lock.o timer.o thread_function.o
 7 OBJS_UNLOCK = main_nolock.o timer.o thread_function.o
 8 OBJS_ATOMICLOCK = main_atomic.o timer.o thread_function.o
 9 
10 INC = timer.h thread_function.h lock.h
11 
12 lock : $(OBJS_LOCK) $(INC) 
13     $(CC) -o mainlock $(OBJS_LOCK) $(CFLAGS)
14     rm *.o
15 
16 nolock : $(OBJS_UNLOCK) $(INC)
17     $(CC) -o mainnolock $(OBJS_UNLOCK) $(CFLAGS)
18     rm *.o
19 
20 atomiclock : $(OBJS_ATOMICLOCK) $(INC)
21     $(CC) -o mainatomic $(OBJS_ATOMICLOCK) $(CFLAGS)
22 
23 main_lock.o : main_lock.cpp 
24     $(CC) -c main_lock.cpp $(CFLAGS)
25 
26 main_nolock.o : main_nolock.cpp 
27     $(CC) -c main_nolock.cpp $(CFLAGS)
28 
29 main_atomic.o : main_atomic.cpp
30     $(CC) -c  main_atomic.cpp $(CFLAGS)
31 
32 timer.o : timer.cpp 
33     $(CC) -c timer.cpp $(CFLAGS)
34 
35 thread_function.o : thread_function.cpp
36     $(CC) -c thread_function.cpp $(CFLAGS)
37 
38 clean:
39     rm *.o  

执行makefile

make lock

make nolock

make atomiclock

然后生成3个可执行文件 

运行这3个可执行文件:

另外:针对main_nolock.cpp而言,作者提到了一个现象

在thread_function.cpp中, 随着一下代码的改变,运行时间会有变化

while (!(__sync_bool_compare_and_swap (&mutex,lock, 1) )); 

while (!(__sync_bool_compare_and_swap (&mutex,lock, 1) )) usleep(1);

while (!(__sync_bool_compare_and_swap (&mutex,lock, 1) ))usleep(10);

while (!(__sync_bool_compare_and_swap (&mutex,lock, 1) ))usleep(100);

while (!(__sync_bool_compare_and_swap (&mutex,lock, 1) ))usleep(1000);

while (!(__sync_bool_compare_and_swap (&mutex,lock, 1) ))usleep(10000);

while (!(__sync_bool_compare_and_swap (&mutex,lock, 1) ))usleep(100000);

执行时间的关系是  :    T(;)<T(1)<T(10)<T(100)<T(1000)<T(10000)>T(100000)

 通过编程测试及测试得出结论:
1、如果是想用全局变量来做统计操作。而又不得不考虑多线程间的互斥访问的话,最好使用编译器支持的原子操作函数。再满足互斥访问的前提下,编程最简单,效率最高。

2、lock-free,无锁编程方式确实能够比传统加锁方式效率高。所以在高并发程序中采用无锁编程的方式可以进一步提高程序效率。但是得对无锁方式有足够熟悉的了解,不然效率反而会更低而且容易出错。(比如在某些情况下main_nolock比main_lock的效率还要低)

在学习一个无锁化编程的分析帖子 http://blog.csdn.net/hzhsan/article/details/25141421

Lock-free 算法通常比基于锁的算法要好:

  • 从其定义来看,它们是 wait-free 的,可以确保线程永远不会阻塞。
  • 状态转变是原子性的,以至于在任何点失败都不会恶化数据结构
  • 因为线程永远不会阻塞,所以当同步的细粒度是单一原子写或比较交换时,它们通常可以带来更高的吞吐量
  • 在某些情况下,lock-free 算法会有更少的同步写操作(比如 Interlocked 操作),因此纯粹从性能来看,它可能更便宜

但是 lock-freedom 并不是万能药。下面是一些很明显的不利因素:

  • 乐观的并发使用会对 hot data structures 导致 livelock。
  • 代码需要大量困难的测试。通常其正确性取决于对目标机器内存模型的正确解释。
  • 基于众多原因,lock-free 代码很难编写和维护
无锁编程与分布式编程那个更适合多核CPU?
无锁编程主要是使用原子操作替代锁来实现对共享资源的访问保护,举个例子,要对某个整数变量进行加1操作的话,用锁保护操作的代码如下:
int a = 0;
Lock();
a+= 1;
Unlock();
如果对上述代码反编译可以发现 a+=1;被翻译成了以下三条汇编指令:
mov eax,dword ptr [a]
add eax,1
mov dword ptr [a],eax
如果在单核系统中,由于在上述三条指令的任何一条执行完后都可能发生任务切换,比如执行完第1条指令后就发生了任务切换,这时如果有其他任务来对a进行操作的话,当任务切换回来后,将继续对a进行操作,很可能出现不可预测的结果,因此上述三条指令必须使用锁来保护,以使这段时间内其他任务无法对a进行操作。
需要注意的是 ,在多核系统中,因为多个CPU核在物理上是并行的,可能发生同时写的现象;所以必须保证一个CPU核在对共享内存进行写操作时,其他CPU核不能写这块内存。因此在多核系统中和单核有区别,即使只有一条指令,也需要要加锁保护。
如果使用原子操作来实现上述加1操作的话,例如使用VC里的InterlockedIncrement来操作的话,那么对a的加1操作需要以下语句
InterlockedIncrement (&a);
这条语句最终的实际加1操作会被翻译成以下一条带lock前缀的汇编指令:
lock xadd dword ptr [ecx],eax
使用原子操作时,在进行实际的写操作时,使用了lock指令,这样就可以阻止其他任务写这块内存,避免出现数据竞争现象。原子操作速度比锁快,一般要快一倍以上。
使用lock前缀的指令实际上在系统中是使用了内存栅障(memory barrier),当原子操作在进行时,其他任务都不能对内存操作,会影响其他任务的执行。因此这种原子操作实际上属于一种激烈竞争的锁,不过由于它的操作时间很快,因此可以看成是一种极细粒度锁。
在无锁(Lock-free)编程环境中,主要使用的原子操作为 CAS(Compare and Swap)操作,在VC里对应的操作为InterlockedCompareExchange或者InterlockedCompareExchangeAcquire;如果是64位的操作,需要使用InterlockedCompareExchange64或者InterlockedCompareExchangeAcquire64。 使用这种原子操作替代锁的最大的一个好处是它是非阻塞的。
 

 

 
比较项目
无锁编程
分布式编程
1
加速比性能
取决于竞争方式,除非也采用分布式竞争,否则不如分布式锁竞争的性能
加速比和CPU核数成正比关系,接近于单核多任务时的性能
2
实现的功能
有限
不受限制
3
程序员掌握难易程度
难度太高,过于复杂,普通程序员无法掌握,目前世界上只有少数几个人掌握。
和单核时代的数据结构算法难度差不多,普通程序员可以掌握
4
现有软件的移植
使用无锁算法后,以往的算法需要废弃掉,无法复用
可以继承已有的算法,在已有程序基础上重构即可。

 

 
从上表的四个方面的综合比较可以看出, 无锁编程的实用价值是远远不如分布式编程的,因此分布式编程比无锁编程更适合多核CPU系统

 

可在分布计算机系统的几台计算机上同时协调执行的程序设计方法,分布式程序设计的主要特征是分布和通信。采用分布式程序设计方法设计程序时,一个程序由若干个可独立执行的程序模块组成。这些程序模块分布于一个分布式计算机系统的几台计算机上同时执行。分布在各台计算机上的程序模块是相互关联的,它们在执行中需要交换数据,即通信。只有通过通信,各程序模块才能协调地完成一个共同的计算任务。采用分布式程序设计方法解决计算问题时,必须提供用以进行分布式程序设计的语言和设计相应的分布式算法。分布式程序设计语言与常用的各种程序设计语言的主要区别,在于它具有程序分布和通信的功能。因此,分布式程序设计语言,往往可以由一种程序设计语言增加分布和通信的功能而构成。分布式算法和适用于多处理器系统的并行算法,都具有并行执行的特点,但它们是有区别的。设计分布式算法时,必须保证实现算法的各程序模块间不会有公共变量,它们只能通过通信来交换数据。此外,设计分布式算法时,往往需要考虑坚定性,即当系统中几台计算机失效时,算法仍是有效的。

转载于:https://www.cnblogs.com/silentNight/p/5685629.html

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

__sync_fetch_and_add 的相关文章

  • linux间文件实时同步(syncthing) ---带历史版本“后悔药”

    一 概念简介 syncthing 一款开源免费的数据同步工具 基于P2P的跨平台文件同步工具 通过tcp建立设备连接 再通过TLS进行数据安全传输 支持公网与局域网搭建 支持单双向同步与历史版本控制 后悔药 备份机未感染情况下 历史版本理论
  • createObjectURL 错误:`参数必须是 Blob 的实例。收到 Blob 的实例`

    我有一条快速路线 其中包含以下内容 let result await fetch http someurl result await result blob console log result const img URL createOb
  • 使用 fetch 进行 WebAudio 流式传输:DOMException:无法解码音频数据

    我正在尝试使用 Chrome 51 播放来自 fetch API 的无限流 网络摄像头音频流为 Microsoft PCM 16 位 单声道 11025 Hz 该代码对于 mp3 文件几乎可以正常工作 除了一些小故障 但它对于 wav 文件
  • 是否可以从获取的 url 而不是规范的 url 中提取元数据?

    我有一个像这样的 Facebook 链接到我没有完全控制权的页面 我可以修改但不是页面的 因此 我尝试在我拥有完全控制权的新页面上设置 like 按钮的链接 在此页面上设置opengraph元标记 并设置一个链接到原始页面的og url 但
  • MYSQL 缺少第一行数据[重复]

    这个问题在这里已经有答案了 我编写了一个 PHP 脚本 其中返回餐厅名称 地址 电话号码 营业时间表和自定义菜单的链接 但是 即使数据库中有周一的条目 当我在 mysqli fetch assoc 中执行 while 循环时 它也不会显示
  • 我可以在 Perl 中抑制来自 fetch.pm 的错误消息吗

    当使用 Fetch 从 Teamcity 下载 url 时 我收到 Fetch failed 错误 但文件的下载确实有效 他们最近更改了我们的 Teamcity 服务器的权限 因此我在获取要下载的文件的 URL 时必须使用用户名和密码 我只
  • 我的提取请求被取消,我不知道为什么

    我正在创建一个网络应用程序 它消耗https restcountries eu API 当用户输入国家 地区时 我将使用以下命令向 API 发出请求fetch 然而 我的请求总是被取消 我测试了捕获用户输入的部分 但我认为问题出在我的fet
  • 从 React 组件进行 REST 调用

    我正在尝试从 React 组件进行 REST 调用并将返回的 JSON 数据渲染到 DOM 中 这是我的组件 import React from react export default class ItemLister extends R
  • 保存和删除 NSManagedObject 和 NSManagedObjectContext

    三个问题 但它们都是相关的 如果您愿意 我可以将它们分为三个问题 以便您获得更多学分 如果您愿意我这样做 请告诉我 我有以下代码允许我访问 NSManagedObject self managedObjectContext STAppDel
  • Lua:获取网页

    我想获取一个网页并以字符串形式获取结果 但我不知道该怎么做 我在网上搜索并没有找到如何操作 我只想用Lua套接字 http w3 impa br diego software luasocket其中带有一个http子模块 http w3 i
  • 如何在酶中等待私人功能的承诺?

    我是 React 和任何 JavaScript 测试框架的新手 我有一个简单的组件 可以从 API 检索项目并将其显示在屏幕上 函数 getItems 是从 componentWillMount 调用的 是否可以等到 getItems 完成
  • Nativescript 图像转为 Base64,然后获取 POST

    如何对图像进行 Base64 处理 以便适合使用 NativeScript 获取模块发送 这是使用测试服务器的情况的基本演示 use strict var imageSourceModule require image source fun
  • 获取数据后reactjs useEffect清理功能

    我已经阅读了一些使用 useEffect 的 Reactjs 良好实践 我遇到一种情况 我将函数分开来获取数据并在 useEffect 挂钩上调用它 在这种情况下我怎样才能做一些清理功能呢 我见过一些像这样的 useEffect 清理 us
  • git fetch 仅适用于当前分支

    我知道我可以将任何远程分支获取到任何本地分支 https stackoverflow com questions 6368987 how do i fetch only one branch of a remote git reposito
  • Office 脚本(Excel 网页版)获取错误

    我正在尝试从 Web 上的 Excel 调用外部 API 但是 我一直试图从 fetch 调用中获取结果 我什至使用 Office 文档示例来确保 在 Excel 中 单击自动化以创建新脚本 async function main work
  • Express JS 路由中使用 formData 获取 POST 为空

    我有一个表单 它使用 fetch 到 AJAX 并在 NodeJS 上有一个路由 当 AJAX POST 命中路由时 req body 显示一个空对象 这是代码 在 app js 中 app use bodyParser json app
  • django-orm 不区分大小写的顺序

    我知道 我可以从 DJango ORM 运行不区分大小写的搜索 喜欢 User objects filter first name contains jake User objects filter first name contains
  • 将数据库导入 MATLAB 错误

    我正在尝试将表导入到我的 MATLAB 工作区 但它一直向我抛出错误 Undefined function or method fetch for input arguments of type struct 这是我尝试执行的代码 dyn
  • 实现批量记录获取

    在程序开始时 我需要将数据从 MS Access 数据库 mdb 读取到下拉控件中 这样做是为了每当用户在该控件中键入内容时 应用程序都可以自动完成 不管怎样 从数据库中读取数据花了很长时间 所以我想我应该实现批量行获取 这是我的代码 CS
  • fetch 被告知调用 http 资源,但它改为调用 https 资源

    这是我在 React 应用程序中的代码 我正在使用 JS 原生 fetch fetch http signup momeas com index php user email timezone tz mode no cors method

随机推荐

  • javascript/Jquery 将字符串转换成变量名

    var a 61 39 a 39 39 b 39 39 c 39 var obj 61 for i 61 0 i lt a length i 43 43 obj a i 61 34 abc 34 43 1 alert obj a alert
  • Navicat 看历史执行SQL

    Navicat可以通过这个框口看手动操作所执行的代码操作 转载于 https www cnblogs com sunxun p 5286657 html
  • MWC四轴飞行器代码解读

    MWC v2 2 代码解读annexCode 红色是一些暂时没去顾及的部分 xff0c 与我现在关心的地方并无太大关系 函数对rcDate进行处理 xff08 去除死区 xff0c 根据油门曲线 xff0c roll pitch曲线 xff
  • 云讷科技推出Kerloud数传电台

    介绍 Kerloud Telemetry是由云讷科技推出的一款面向无人系统 传输可靠的短距离无线传输电台 产品基于ISM Sub G频段 xff0c 采用FSK调制 抗干扰能力强 xff0c 具备Uart USB通用接口 xff0c 支持P
  • Requests方法 --- post 请求body的四种类型

    常见的 post 提交数据类型有四种 xff1a 1 第一种 xff1a application json xff1a 这是最常见的 json 格式 xff0c 也是非常友好的深受小伙伴喜欢 的一种 xff0c 如下 34 input1 3
  • 中文转拼音 (utf8版,gbk转utf8也可用)

    中文转拼音 utf8版 gbk转utf8也可用 https git oschina net cik pinyin php 64 param string str utf8字符串 64 param string ret format 返回格式
  • Pycharm激活方法(license server方法)

    strong pycharm所有版本 span class hljs string http span class hljs comment www jetbrains com pycharm download previous html
  • idc函数大全

    A80 addc A80 addcix A80 addciy A80 addix A80 addiy A80 cmpd A80 cmpi A80 im0 A80 im1 A80 im2 A80 jrc A80 jrnc A80 jrnz A
  • 视觉SLAM漫淡

    视觉SLAM漫谈 1 前言 开始做SLAM xff08 机器人同时定位与建图 xff09 研究已经近一年了 从一年级开始对这个方向产生兴趣 xff0c 到现在为止 xff0c 也算是对这个领域有了大致的了解 然而越了解 xff0c 越觉得这
  • 无人机基础知识点总结

    一 xff0e 基本概念 飞控 xff1a 飞机的控制系统 xff0c 其中硬件包含传感器部分IMU和控制部分的MCU xff0c 软件部分包含控制算法 俯仰 xff1a pitch xff0c 绕坐标系y轴旋转 xff0c 想象一下平时的
  • 谈一谈编程中遇到的一些死循环(递归死循环,AOP死循环,业务死循环)

    最简单最基础死循环 xff0c 一般都是这样的 while 1 while true for 然而在编程中常常会用到一些并不是那么基础的死循环 xff0c 这里列举一些我在编程中所遇到的一些死循环 方法已经不记得了 xff0c 只是大概说明
  • 简历上的项目经历怎么写?这3条原则不可忽视!

    阅读本文大概需要 5 分钟 作者 xff1a 黄小斜 文章来源 xff1a 微信公众号 程序员江湖 作为一个程序员 xff0c 想必大家曾经都做过一些项目 xff0c 可能现在手头上也还有一些项目 不过还是有很多学生朋友来问我 没有项目怎么
  • “四通一达”本一家,这家人是如何“承包”中国快递半壁江山的?

    微博上有张图火到不行了 看明白没 xff1f 原来 xff0c 这些年为我们奔走送快递的申通 中通 圆通 韵达 xff0c 这四家公司 xff0c 以及汇通 天天等快递公司 xff0c 都有一个共同的老家 xff1a 仅有40万人口的浙江桐
  • 在远方

    远方不是脚到达的地方 xff0c 而是心超越的地方 剧情简介 姚远在孤儿院长大 xff0c 后被二叔接出 xff0c 早早进入社会 xff0c 从底层快递员做起 在被邮政执法堵截损失惨重后 xff0c 他设局结识国营邮政稽查负责人的千金路晓
  • c++11 条款21:尽量使用std::make_unique和std::make_shared而不直接使用new

    条款21 xff1a 尽量使用std make unique和std make shared而不直接使用new 让我们从对齐std make unique 和 std make shared这两块开始 std make shared是c 4
  • 快递 10 年,逆袭为王

    2009 2018 xff0c 双十一 全民狂欢已走过十载 xff0c 网购成为了国民消费不可或缺的重要组成 xff0c 并带动了上下游众多产业的狂飙发展 xff0c 这其中 xff0c 以民营快递最为突出 金风玉露一相逢 xff0c 便胜
  • BPDU报文(RSTP)

    与STP 的BPDU报文格式相同 xff0c 就是在flags字段报文中间几位得到应用 主要原理 xff1a 利用flages位中的Proposal与Agreement来进行协商 xff0c 从而快速从 discarding 转成 forw
  • 怎么在一堆身份证中筛选出大于18岁的?

    最近一朋友找我帮个忙 xff0c 让我在N多身份证中找到18岁以上的人 我还想着用SQL查询来弄 xff0c 谁让是干IT的呢 xff0c 没想到被我一个朋友用excel瞬间解决 学习新的东西是多么的重要啊 其实就是利用了excel中的MI
  • 微信小程序我的界面

    前言 感谢 承蒙关照 微信小程序我的界面 界面效果 界面结构 小程序代码 我们先看me json代码 34 navigationBarTitleText 34 34 个人中心 34 me wxml代码 lt view class 61 34
  • __sync_fetch_and_add

    最近在公司离职的前辈写的代码哪里看到了 sync fetch and add这个东东 比较好奇 找些资料学习学习 http www lxway com 4091061956 htm http www cnblogs com FrankTan