Sorry this question not end yet.
I'm trying to write a thread-safe random generator, but
it crashes at
initstate_r(time(NULL), m_state_buff, sizeof(m_state_buff), &m_data);
My gcc version:
gcc version 4.6.3 (Ubuntu/Linaro 4.6.3-1ubuntu5)
#include <stdlib.h>
#include <stdint.h>
#include <stdio.h>
#include <time.h>
class RandomGenerator
{
public:
RandomGenerator()
{
initstate_r(time(NULL), m_state_buff, sizeof(m_state_buff), &m_data);
}
virtual ~RandomGenerator() {}
public:
int32_t get_next_int()
{
#ifdef __GNUC__
static __thread char stat_buff[512];
static __thread random_data buff;
static __thread bool inited = false;
if (!inited)
{
initstate_r(time(NULL), stat_buff, sizeof(stat_buff), &buff);
srandom_r(time(NULL), &buff);
inited = true;
}
int32_t result = 0;
random_r(&buff, &result);
return result;
#endif
}
private:
struct random_data m_data;
char m_state_buff[512];
};
int main()
{
RandomGenerator r;
for (int i = 0; i < 100; ++i)
{
printf("%d\n", r.get_next_int());
}
}
I believe this related to the libc initstate_r() 's bug.
An initialization method should not re-use the buffer's value, it should clean it first.
When I cleanup the buffer before call initstate_r() the segmentation fault has gone.
#include <stdlib.h>
#include <stdint.h>
#include <stdio.h>
#include <time.h>
#include <string.h>
class RandomGenerator
{
public:
RandomGenerator()
{
memset(m_state_buff, 0, sizeof(m_state_buff));
memset(&m_data, 0, sizeof(m_data);
initstate_r(time(NULL), m_state_buff, sizeof(m_state_buff), &m_data);
}
virtual ~RandomGenerator() {}
private:
struct random_data m_data;
char m_state_buff[512];
};
int main()
{
RandomGenerator r;
for (int i = 0; i < 100; ++i)
{
printf("%d\n", r.get_next_int());
}
}
Related
Im trying to make multithreaded proxy checker in c++, when I start the threads and lock it all threads wait till the request is finished. I tried to remove the locks but that doesn't help either. Im using the cpr library to make the requests, the documentation can be found here: https://whoshuu.github.io/cpr/advanced-usage.html.
Reproduceable example:
#include <stdio.h>
#include <pthread.h>
#include <iostream>
#include <queue>
#include <mutex>
#include <cpr/cpr.h>
#include <fmt/format.h>
#define NUMT 10
using namespace std;
using namespace fmt;
std::mutex mut;
std::queue<std::string> q;
void* Checker(void* arg) {
while (!q.empty()) {
mut.lock();
//get a webhook at https://webhook.site
string protocol = "socks4";
string proxyformatted = format("{0}://{1}", protocol, q.front());
auto r = cpr::Get(cpr::Url{ "<webhook url>" },
cpr::Proxies{ {"http", proxyformatted}, {"https", proxyformatted} });
q.pop();
mut.unlock();
}
return NULL;
}
int main(int argc, char** argv) {
q.push("138.201.134.206:5678");
q.push("185.113.7.87:5678");
q.push("5.9.16.126:5678");
q.push("88.146.196.181:4153");
pthread_t tid[NUMT]; int i;
int thread_args[NUMT];
for (i = 0; i < NUMT; i++) {
thread_args[i] = i;
pthread_create(&tid[i], NULL, Checker, (void*) &thread_args);
}
for (i = 0; i < NUMT; i++) {
pthread_join(tid[i], NULL);
fprintf(stderr, "Thread %d terminated\n", i);
}
return 0;
}
Thanks in advance.
I suggest to implement a wrapper class for your queue that will hide the mutex.
That class can provide push(std::string s) and bool pop(std::string& s) that returns true and populate s if the queue wasn't empty or false othervise. Then your worker threads can simply loop
std::string s;
while(q.pop(s)) {
...
}
sorry to bother. Could you know maybe how can i fix my code. It gives me this error:
/usr/include/eigen3/Eigen/src/Core/DenseCoeffsBase.h:365: Eigen::DenseCoeffsBase<Derived, 1>::Scalar& Eigen::DenseCoeffsBase<Derived, 1>::operator()(Eigen::Index, Eigen::Index) [with Derived = Eigen::Matrix<float, -1, -1>; Eigen::DenseCoeffsBase<Derived, 1>::Scalar = float; Eigen::Index = long int]: Assertion `row >= 0 && row < rows() && col >= 0 && col < cols()' failed.
I think that I declared matrix in right way. My mistake (I think) is when i try to fill her with values in Possible transforms function. I think it might be wrong transform1(0, position)=.. I tried it to comment that lines of code and wrote a simple code like transform1(0, position)=1; and it gave the same error.
Sorry to bother,
Kind regards.
My code :
#include "ros/ros.h"
#include <cstdlib>
#include <fstream>
#include <stdio.h>
#include <regex>
#include "sensor_msgs/PointCloud2.h"
#include <pcl_conversions/pcl_conversions.h>
#include <pcl/point_types.h>
#include <pcl/PCLPointCloud2.h>
#include <pcl/conversions.h>
#include <pcl_ros/transforms.h>
#include <boost/shared_ptr.hpp>
#include "pcl_ros/point_cloud.h"
#include "sensor_msgs/PointField.h"
#include <pcl/io/pcd_io.h>
#include "nav_msgs/Odometry.h"
#include "eigen3/Eigen/SVD"
#include "eigen3/Eigen/Dense"
#include "clustering/Track.h"
#include "eigen3/Eigen/Core"
#include "eigen3/Eigen/Sparse"
using namespace Eigen;
int number_od_possible_tracks = 15;
class Odometry_class {
ros::NodeHandle nodeh;
ros::Subscriber sub;
ros::Publisher pub;
public:
Odometry_class();
void Odometry(const sensor_msgs::PointCloud2 &msg);
bool Has_pointcloud_min3points(pcl::PointCloud<pcl::PointXYZIVSI> cloud);
bool Possible_transform(pcl::PointCloud<pcl::PointXYZIVSI> cloud);
void Restore_Ids();
pcl::PointCloud<pcl::PointXYZIVSI> last_cloud;
Eigen::MatrixXf transform1 = (Eigen::MatrixXf(3,15));
Eigen::MatrixXf transform2=(Eigen::MatrixXf(3,15));
int consecutive_Ids_current[15];
int consecutive_Ids_previous[15];
int position;
void Transform();
};
Odometry_class::Odometry_class(){
sub = nodeh.subscribe("trackers", 10, &Odometry_class::Odometry, this);
pub = nodeh.advertise<nav_msgs::Odometry>("odometry", 10);
}
void Odometry_class::Odometry(const sensor_msgs::PointCloud2 &msg ){
pcl::PCLPointCloud2 pcl_pc2;
pcl_conversions::toPCL(msg, pcl_pc2);
pcl::PointCloud<pcl::PointXYZIVSI> cloud;
pcl::fromPCLPointCloud2(pcl_pc2, cloud);
if(Possible_transform(cloud)){
ROS_INFO("Transformation is possible");
}
else{
ROS_INFO("Transformation is not possible");
}
Restore_Ids();
pcl::fromPCLPointCloud2(pcl_pc2, last_cloud);
}
void Odometry_class::Restore_Ids(){
int i=0;
while(consecutive_Ids_current[i]!=0){
consecutive_Ids_current[i]=0;
consecutive_Ids_previous[i]=0;
i++;
}
}
bool Odometry_class::Has_pointcloud_min3points(pcl::PointCloud<pcl::PointXYZIVSI> cloud){
bool has=false;
if(cloud.width>=3){
has=true;
}
return has;
}
bool Odometry_class::Possible_transform(pcl::PointCloud<pcl::PointXYZIVSI> cloud){
bool possible=false;
position=0;
if(Has_pointcloud_min3points(cloud)&Has_pointcloud_min3points(last_cloud)){
for(int i=0;i<cloud.width;i++){
for(int j=0;j<last_cloud.width;j++){
if(cloud[i].id==last_cloud[j].id){
consecutive_Ids_current[position]=i;
consecutive_Ids_previous[position]=j;
position++;
}
}
}
}
if(position>=3){
possible=true;
transform1.resize(3,position);
transform2.resize(3,position);
for(int i=0;i<position;i++){
transform1(0,position)= cloud[consecutive_Ids_current[i]].x;
transform1(1,position)= cloud[consecutive_Ids_current[i]].y;
transform1(2,position)= cloud[consecutive_Ids_current[i]].z;
transform2(0,position)= cloud[consecutive_Ids_previous[i]].x;
transform2(1,position)= cloud[consecutive_Ids_previous[i]].y;
transform2(2,position)= cloud[consecutive_Ids_previous[i]].z;
}
}
return possible;
}
int main(int argc, char **argv) {
ros::init(argc, argv, "Odometry");
Odometry_class Odometry;
ros::spin();
return 0;
}
I think you mixed up your loop variable, i, and upper limit, position. Using position as an index would result in accessing the matrix out of bounds, and the Eigen library catches that in an assertion. Using the loop variable should resolve the error.
transform1(0,i)= cloud[consecutive_Ids_current[i]].x;
And likewise for the rest of the transform1 and transform2 assignments.
Have any one tried anything like this?
Is it possible to print the value of a string or integer on the program itself? Say for example - I have written 2 tests for a program I am trying to call all the tests functions by looping over in a for loop.
A small sample example
#define MAX_TESTS 10
for(test_idx = 0; test_idx<MAX_TESTS; ++test_idx)
{
test_##test_idx();
//Here the output will be more like "test_test_idx();"
//But I am looking for something like
//"test_0();"
//"test_1();"
//"test_2();"
.
.
.
//"test_9();"
}
Is there a way to do it in C?
Complete Program
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
//Macros
#define MAX_TEST 2
#define _MYCAT(a,b) a##b()
void test_0()
{
printf("Test 0\n");
}
void test_1()
{
printf("Test 1 \n");
}
int main()
{
printf("Max Product Testing \n");
for (int test_idx=0; test_idx<MAX_TEST; ++test_idx)
{
/* Try - 1
char buffer[50];
int n = sprintf(buffer, "test_%d", test_idx);
printf("%s %d \n", buffer, n);
*/
//Try - 2
//_MYCAT(test_, test_idx);
}
return 0;
}
The closet you can get in C++ is to keep a map of function names to functions as follows:
#include <iostream>
#include <unordered_map>
#include <string>
#include <functional>
using namespace std;
void test_0()
{
printf("Test 0\n");
}
void test_1()
{
printf("Test 1 \n");
}
int main() {
unordered_map<string, function<void()>> func_map;
func_map["test_0"] = test_0;
func_map["test_1"] = test_1;
for(int i = 0; i < 2; ++i) {
func_map.at("test_" + to_string(i))();
}
return 0;
}
You can make an array of function pointers and call each one in a loop.
Example:
#include <stdio.h>
void test_0()
{
printf("Test 0\n");
}
void test_1()
{
printf("Test 1\n");
}
void test_2()
{
printf("Test 2\n");
}
int main()
{
void(*a)() = test_0;
void(*b)() = test_1;
void(*c)() = test_2;
const int SIZE = 3;
void(*arr[SIZE])() = {
{ a }, { b }, { c }
};
for (int i = 0; i < SIZE; ++i) {
arr[i]();
}
return 0;
}
Output:
Test 0
Test 1
Test 2
I get this error when trying to compile my program:
Field '__jmpbuf' could not be resolved
I looked for a solution for hours and can't seem to find out where is the culprit.
The Thread.h file contains the header of the class. It has the private member:
sigjmp_buf _env;
And the implementation is inside Thread.cpp:
#include "Thread.h"
#include <setjmp.h>
#include "translateAdd.h"
#include <stdio.h>
#include <signal.h>
#include <unistd.h>
#include <sys/time.h>
#define COUNTER_INIT -1
int Thread::_idCounter = COUNTER_INIT;
Thread::Thread(void (*threadsFunc)(void))
: threadsFunction(threadsFunc), _stack(new char[STACK_SIZE]), _quantums(1)
{
address_t sp, pc;
sp = (address_t)_stack + STACK_SIZE - sizeof(address_t);
pc = (address_t)threadsFunc;
// set environment for later return
sigsetjmp(_env, 1);
(_env->__jmpbuf)[JB_SP] = translate_address(sp);
(_env->__jmpbuf)[JB_PC] = translate_address(pc);
sigemptyset(&_env->__saved_mask);
_id = ++_idCounter;
_state = READY;
}
EDIT: Using eclipse as the IDE under ubuntu 32bit
EDIT: Another complete example that doesn't compile on my machine:
#include <stdio.h>
#include <setjmp.h>
#include <signal.h>
#include <unistd.h>
#include <sys/time.h>
#define SECOND 1000000
#define STACK_SIZE 4096
char stack1[STACK_SIZE];
char stack2[STACK_SIZE];
sigjmp_buf env[2];
#ifdef __x86_64__
/* code for 64 bit Intel arch */
typedef unsigned long address_t;
#define JB_SP 6
#define JB_PC 7
/* A translation is required when using an address of a variable.
Use this as a black box in your code. */
address_t translate_address(address_t addr)
{
address_t ret;
asm volatile("xor %%fs:0x30,%0\n"
"rol $0x11,%0\n"
: "=g" (ret)
: "0" (addr));
return ret;
}
#else
/* code for 32 bit Intel arch */
typedef unsigned int address_t;
#define JB_SP 4
#define JB_PC 5
/* A translation is required when using an address of a variable.
Use this as a black box in your code. */
address_t translate_address(address_t addr)
{
address_t ret;
asm volatile("xor %%gs:0x18,%0\n"
"rol $0x9,%0\n"
: "=g" (ret)
: "0" (addr));
return ret;
}
#endif
void switchThreads(void)
{
static int currentThread = 0;
int ret_val = sigsetjmp(env[currentThread],1);
printf("SWITCH: ret_val=%d\n", ret_val);
if (ret_val == 1) {
return;
}
currentThread = 1 - currentThread;
siglongjmp(env[currentThread],1);
}
void f(void)
{
int i = 0;
while(1){
++i;
printf("in f (%d)\n",i);
if (i % 3 == 0) {
printf("f: switching\n");
switchThreads();
}
usleep(SECOND);
}
}
void g(void)
{
int i = 0;
while(1){
++i;
printf("in g (%d)\n",i);
if (i % 5 == 0) {
printf("g: switching\n");
switchThreads();
}
usleep(SECOND);
}
}
void setup(void)
{
address_t sp, pc;
sp = (address_t)stack1 + STACK_SIZE - sizeof(address_t);
pc = (address_t)f;
sigsetjmp(env[0], 1);
(env[0]->__jmpbuf)[JB_SP] = translate_address(sp);
(env[0]->__jmpbuf)[JB_PC] = translate_address(pc);
sigemptyset(&env[0]->__saved_mask);
sp = (address_t)stack2 + STACK_SIZE - sizeof(address_t);
pc = (address_t)g;
sigsetjmp(env[1], 1);
(env[1]->__jmpbuf)[JB_SP] = translate_address(sp);
(env[1]->__jmpbuf)[JB_PC] = translate_address(pc);
sigemptyset(&env[1]->__saved_mask);
}
int main(void)
{
setup();
siglongjmp(env[0], 1);
return 0;
}
If you really need to use the internal fields (which will only be valid for your compiler on your system) you need to check the types:
typedef struct __jmp_buf_tag sigjmp_buf[1];
That means that sigjmp_buf is not a pointer, but an array with a single structure in it. So you use it like a normal array of structures:
sigjmp_buf _env;
_env[0].__jmpbuf[x] = y;
I really recommend against the use the internal field of this structure. Linux have other functions to simplify cooperative threading (which is what you seem to be implementing).
I have a problem with the code OpenKinect provides. I'm trying to use the Kinect with c++, but I get this error. On the web this question was already asked, but I have not find a decent answer. The code is this:
#include <cstdlib>
#include "libfreenect.h"
#include "libfreenect.hpp"
#include <pthread.h>
#include <stdio.h>
#include <iostream>
#include <string.h>
#include <cmath>
#include <vector>
#if defined(__APPLE__)
#include <GLUT/glut.h>
#include <OpenGL/gl.h>
#include <OpenGL/glu.h>
#else
#include <GL/glut.h>
#include <GL/gl.h>
#include <GL/glu.h>
#endif
using namespace std;
class Mutex {
...
};
class MyFreenectDevice : public Freenect::FreenectDevice {
public:
MyFreenectDevice(freenect_context *_ctx, int _index)
: Freenect::FreenectDevice(_ctx, _index),
m_buffer_depth(freenect_find_video_mode(FREENECT_RESOLUTION_MEDIUM, FREENECT_VIDEO_RGB).bytes),
m_buffer_video(freenect_find_video_mode(FREENECT_RESOLUTION_MEDIUM, FREENECT_VIDEO_RGB).bytes),
m_gamma(2048),
m_new_rgb_frame(false),
m_new_depth_frame(false)
{
for (unsigned int i = 0; i < 2048; i++) {
float v = i / 2048.0;
v = std::pow(v, 3) * 6;
m_gamma[i] = v * 6 * 256;
}
}
...
private:
std::vector<uint8_t> m_buffer_depth;
std::vector<uint8_t> m_buffer_video;
std::vector<uint16_t> m_gamma;
Mutex m_rgb_mutex;
Mutex m_depth_mutex;
bool m_new_rgb_frame;
bool m_new_depth_frame;
};
Freenect::Freenect freenect;
MyFreenectDevice* device;
freenect_video_format requested_format(FREENECT_VIDEO_RGB);
...
I get the error Unable to resolve identifier identifier freenect for the instruction Freenect::Freenect freenect;.
The code of this template is in the libfreenect.hpp code:
class Freenect : Noncopyable {
private:
typedef std::map<int, FreenectDevice*> DeviceMap;
public:
...
template <typename ConcreteDevice>
ConcreteDevice& createDevice(int _index) {
DeviceMap::iterator it = m_devices.find(_index);
if (it != m_devices.end()) delete it->second;
ConcreteDevice * device = new ConcreteDevice(m_ctx, _index);
m_devices.insert(std::make_pair<int, FreenectDevice*>(_index, device));
return *device;
}
...
}
I have no idea of what is the problem, this is the official code and it should work.. any suggestions? thanks in advance